C# 指定类本身的泛型类上的基类约束
昨天,我向朋友们解释了C#的一般约束。在演示C# 指定类本身的泛型类上的基类约束,c#,generics,type-parameter,generic-constraints,C#,Generics,Type Parameter,Generic Constraints,昨天,我向朋友们解释了C#的一般约束。在演示where T:CLASSNAME约束时,我突然想到了如下内容: public class UnusableClass<T> where T : UnusableClass<T> { public static int method(T input){ return 0; } } public class BinaryTree:TreeNode<BinaryTree> { } 公共
where T:CLASSNAME
约束时,我突然想到了如下内容:
public class UnusableClass<T> where T : UnusableClass<T>
{
public static int method(T input){
return 0;
}
}
public class BinaryTree:TreeNode<BinaryTree>
{
}
公共类UnusableClass,其中T:UnusableClass
{
公共静态int方法(T输入){
返回0;
}
}
看到它被编译,我真的很惊讶。然而,经过一番思考,我认为从编译器的角度来看,它是完全合法的-UnusableClass
与此约束中可以使用的任何其他类一样,都是一个类
然而,这留下了几个问题:这个类如何使用?有可能吗
int方法
T
的类型是什么
如果这些都是可能的,T的类型是什么
它们都是可能的,您将决定T
的类型。例如,让我们假设有一个类型继承自UnusableClass
然后T
的类型变为Foo
,如果您试图调用method
,则需要传递Foo的实例
public class Implementation : UnusableClass<Implementation>
{
}
公共类实现:UnusableClass
{
}
是完全有效的,因此
var unusable = new UnusableClass<Implementation>();
var unusable=新的UnusableClass();
及
UnusableClass.method(新实现());
有效
因此,是的,它可以通过提供一个继承类型作为类型参数来实例化,并且与调用静态方法类似。例如,它对于树状结构非常有用,在树状结构中,您希望一般指定节点具有的子节点的类型,而节点本身是相同的类型。此方法广泛用于树和其他类似图形的结构中。在这里,您要对编译器说,T有一个无法使用的类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;
}
}
公共类树节点
其中T:TreeNode
{
公共T This{get{将其作为T;}返回
公共T父{get;set;}
公共列表子项{get;set;}
公共虚拟void AddChild(T child)
{
儿童。添加(儿童);
child.Parent=This;
}
公共虚拟void SetParent(T parent)
{
parent.Childrens.Add(此);
父母=父母;
}
}
然后像这样使用它:
public class UnusableClass<T> where T : UnusableClass<T>
{
public static int method(T input){
return 0;
}
}
public class BinaryTree:TreeNode<BinaryTree>
{
}
公共类二进制树:TreeNode
{
}
Hmm。。闻起来像是家庭作业。@JamieKeeling:不,不太像。我只是对它是否可能感兴趣=)我的朋友们完全确定它不是,但我有我的疑问…它是递归类型的一个好模式,如树和图。在几乎所有其他情况下,它都会成为一种反模式,使代码复杂化并降低可读性。我记得我以前工作的代码库,在那里到处都使用。它仍然让我不寒而栗。关联:这不就是F-有界多态性吗?
public class BinaryTree:TreeNode<BinaryTree>
{
}