昨天,我向朋友解释了C#的通用限制。在演示where T : CLASSNAME
约束时,我掀起了类似的东西:
public class UnusableClass<T> where T : UnusableClass<T>
{
public static int method(T input){
return 0;
}
}
看到它编译后真的很惊讶。然而,经过一番思考后,我认为从编译器的角度来看它是完全合法的 - UnusableClass<T>
和其他任何可用于此约束的类一样多。
然而,这留下了几个问题:如何使用这个课程?是否可能
int method
?如果是的话,怎么样?
如果中的任何一个可能,那么T
的类型是什么?
答案 0 :(得分:13)
这种方法广泛用于树和其他类图结构。在这里你对编译器说,T有UnusableClass的API。也就是说,您可以按如下方式实现TreeNode:
public class TreeNode<T>
where T:TreeNode<T>
{
public T This { get { return this as T;} }
public T Parent { get; set; }
public List<T> Childrens { get; set; }
public virtual void AddChild(T child)
{
Childrens.Add(child);
child.Parent = This;
}
public virtual void SetParent(T parent)
{
parent.Childrens.Add(This);
Parent = parent;
}
}
然后像这样使用它:
public class BinaryTree:TreeNode<BinaryTree>
{
}
答案 1 :(得分:8)
好。
public class Implementation : UnusableClass<Implementation>
{
}
完全有效,因此
var unusable = new UnusableClass<Implementation>();
和
UnusableClass<Implementation>.method(new Implementation());
有效。
所以,是的,它可以通过提供继承类型作为类型参数来实例化,并且类似于对静态方法的调用。例如,对于你想要一般性地指定节点所拥有的子类型的树状结构,它是有用的,而它本身就是同一类型。
答案 2 :(得分:5)
如果其中任何一种可能,那么T的类型是什么?
他们都是可能的,你就是那个决定T
类型的人。例如我们假设有一种类型继承自UnusableClass<T>
class Foo : UnusableClass<Foo> { }
现在您可以实例化UnusableClass<Foo>
因为Foo
满足约束条件:
UnusableClass<Foo> f = new UnusableClass<Foo>();
然后T
的类型变为Foo
,如果您尝试拨打method
,则需要传递Foo
的实例。