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();
}
}
Run Code Online (Sandbox Code Playgroud)
为什么这是非法的?它期望我为类的方法调用提供一个类型参数,这是没有意义的.泛型类或方法不能用于静态上下文中的类型参数.
它要我写这样的电话:
var bst = BinarySearchTree<foo>.InitializeSampleCharacterBST();
Run Code Online (Sandbox Code Playgroud)
其中foo可以是我想要的任何类型,而不管静态方法调用返回特定类型的通用对象.
班级BinarySearchTree和BinarySeachTree<Foo>完全分开; 该语言允许泛型类型重载.也许在非泛型双胞胎类上声明此方法:
public static class BinarySearchTree {
public static BinarySearchTree<char> InitializeSampleCharacterBST() {...}
}
public class BinarySearchTree<T> {...} // rest of the code
Run Code Online (Sandbox Code Playgroud)
否则...... T会用什么?如果静态方法与静态字段对话怎么办?更不用说使用哪个T,每个都 T获得不同的静态字段(即SomeType<Foo>具有单独的字段SomeType<Bar>).
正如Marc所说,将类型重载为非泛型类有时很有用 - 在这种情况下也是如此.
至于为什么有必要,假设静态方法实际上实现为:
public static BinarySearchTree<char> InitializeSampleCharacterBST()
{
Console.WriteLine(typeof(T));
return null;
}
Run Code Online (Sandbox Code Playgroud)
这将是完全有效的代码 - 它是一个泛型类型,因此它应该可以访问类型参数...但是你试图在不提供泛型类型参数的情况下调用该方法,因此它无法工作.在你的情况下,你碰巧不在方法中的T任何地方使用,但这是巧合.这有点像有一个不使用的实例方法this:你没有使用实例,但你仍然无法将其称为静态方法.
除了具有单独的静态类之外,另一种可能有用的设计技术是将您的类型拆分为非泛型和通用部分.这样,如果你可以很难找出你所拥有的确切类型,你实际上并不需要知道它以便调用一些成员.例如,集合接口层次结构可能具有:
public interface ISomeCollection
{
int Count { get; }
void Clear();
}
public interface ISomeCollection<T> : ISomeCollection
{
void Add(T item);
}
Run Code Online (Sandbox Code Playgroud)
我自己使用这种技术作为C#的Protocol Buffers端口,并且它被证明非常有用(如果有点复杂).