繁体   English   中英

为什么泛型类型的静态方法需要Type参数?

[英]Why does a static method on a generic type require a Type parameter?

public class BinarySearchTree<T>
where T : IComparable<T>
{
    public static BinarySearchTree<char> InitializeSampleCharacterBST()
    {
        var bst = new BinarySearchTree<char>();

        bst.Insert('F');
        bst.Insert('B');
        bst.Insert('A');
        bst.Insert('D');
        bst.Insert('C');
        bst.Insert('G');
        bst.Insert('I');
        bst.Insert('H');

        return bst;
    }

class Program
{
        static void Main(string[] args)
        {
            var bst = BinarySearchTree.InitializeSampleCharacterBST();
        }
}

为什么这是非法的? 期望我为没有意义的类的方法调用提供类型参数。 泛型类或方法在静态上下文中没有使用类型参数。

它想让我这样写电话:

var bst = BinarySearchTree<foo>.InitializeSampleCharacterBST();

foo可以是我想要的任何类型,而不管静态方法调用返回特定类型的泛型对象的事实。

BinarySearchTreeBinarySeachTree<Foo>完全分开; 该语言允许泛型类型重载。 也许在非泛型孪生类上声明此方法:

public static class BinarySearchTree {
    public static BinarySearchTree<char> InitializeSampleCharacterBST() {...}
}
public class BinarySearchTree<T> {...} // rest of the code

否则...它将使用什么T 而且,如果静态方法与静态字段对话怎么办? 更不用说要使用哪个T了, 每个 T都会获得不同的静态字段(即SomeType<Foo>SomeType<Bar>具有不同的字段)。

正如Marc所说的,有时将类型重载为具有非泛型类很有用-在这种情况下就是如此。

至于为什么有必要,假设静态方法实际上实现为:

public static BinarySearchTree<char> InitializeSampleCharacterBST()
{
    Console.WriteLine(typeof(T));
    return null;
}

那将是完全有效的代码-它是泛型类型,因此它应该可以访问类型参数...但是您尝试在不提供泛型类型参数的情况下调用该方法,因此它可能无法工作。 在您的情况下,您碰巧不在方法中的任何地方使用T ,但这是一个巧合。 这有点像拥有一个不使用this方法的实例方法:您没有使用该实例,但是您仍然无法像调用静态方法一样调用它。

除了具有单独的静态类之外,另一种有用的设计技术是将您的类型分成非通用和通用部分。 这样,在弄清楚您拥有哪种确切类型的情况下,您实际上不需要知道它即可调用某些成员。 例如,收集接口层次结构可能具有:

public interface ISomeCollection
{
    int Count { get; }
    void Clear();
}

public interface ISomeCollection<T> : ISomeCollection
{
    void Add(T item);
}

我已经在C#的Protocol Buffers端口中使用了此技术,事实证明它非常有用(如果有些复杂的话)。

您忘记了类型参数不仅会出现在方法的参数/返回类型中。 它们也可以出现在实现中:

public static BinarySearchTree<char> InitializeSampleCharacterBST()
{
    var forSomeReason = new T();

通过将您的方法放在带有类型参数的静态类中,您的意思是该方法的实现可能(现在或将来会修订)取决于该类型参数。

如果不是这种情况,则将方法放在错误的位置。

因为类型本身是泛型的,所以即使您感兴趣的静态方法不使用该类型参数,也必须提供一个类型参数。 它只是C#中泛型的性质...它们在任何时候都不以非泛型形式存在。 如果这样做,将与同类型的非通用版本产生冲突。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM