泛型类的基类约束指定类本身
Posted
技术标签:
【中文标题】泛型类的基类约束指定类本身【英文标题】:Base class constraint on generic class specifying the class itself 【发布时间】:2015-03-24 09:09:13 【问题描述】:昨天,我正在向我的朋友解释 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
的类型会是什么?
【问题讨论】:
嗯......闻起来像家庭作业。 @JamieKeeling:不,不是真的。我只是对它是否可能感兴趣=)我的朋友完全确定它不是,但我有我的怀疑...... 这是递归类型的好模式,如树和图。在几乎所有其他情况下,它都会成为一种反模式,它会使代码复杂化并使其可读性降低。我记得我之前工作中的代码库,到处都在使用它。它仍然让我颤抖。 相关:Curiously recurring template pattern 这不就是F-bounded Polymorphism吗? 【参考方案1】:这种方法广泛用于树和其他类似图形的结构中。这里你对编译器说,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>
【讨论】:
【参考方案2】:嗯。
public class Implementation : UnusableClass<Implementation>
完全有效,因此
var unusable = new UnusableClass<Implementation>();
和
UnusableClass<Implementation>.method(new Implementation());
有效。
所以,是的,它可以通过提供继承类型作为类型参数来实例化,类似地调用静态方法。例如,它对树状结构很有用,在这种结构中,您希望一般地指定节点具有的子节点的类型,而节点本身的类型相同。
【讨论】:
【参考方案3】:如果这些都是可能的,T 的类型是什么?
它们都是可能的,而你将决定T
的类型。例如,假设有一个继承自UnusableClass<T>
的类型
class Foo : UnusableClass<Foo>
现在您可以实例化UnusableClass<Foo>
,因为Foo
满足约束:
UnusableClass<Foo> f = new UnusableClass<Foo>();
然后T
的类型变为Foo
,如果您尝试调用method
,则需要传递Foo
的实例。
【讨论】:
以上是关于泛型类的基类约束指定类本身的主要内容,如果未能解决你的问题,请参考以下文章