10

昨天,我正在向我的朋友解释 C# 的通用约束。在演示where T : CLASSNAME约束时,我做了这样的事情:

public class UnusableClass<T> where T : UnusableClass<T>
{
    public static int method(T input){
        return 0;
    }
}

看到它编译真的很惊讶。然而,经过一番思考,我认为从编译器的角度来看它是完全合法的 -UnusableClass<T>与可以在此约束中使用的任何其他类一样多。

然而,这留下了几个问题:如何使用这个类?是否有可能

  1. 实例化它?
  2. 继承它?
  3. 调用它的静态方法int method

如果是,如何?

如果其中任何一个可能的,那将是什么类型T

4

3 回答 3

14

这种方法广泛用于树和其他类似图的结构中。这里你对编译器说,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>
{
}
于 2015-03-24T09:16:12.007 回答
8

出色地。

public class Implementation : UnusableClass<Implementation>
{
}

是完全有效的,因此使得

var unusable = new UnusableClass<Implementation>();

UnusableClass<Implementation>.method(new Implementation());

有效的。

所以,是的,它可以通过提供继承类型作为类型参数来实例化,并且与调用静态方法类似。例如,它对于您想要一般指定节点具有的子节点类型的树状结构很有用,而它本身是相同的类型。

于 2015-03-24T09:13:58.983 回答
5

如果其中任何一个是可能的,那么 T 的类型是什么?

它们都是可能的,而您将决定 . 的类型是什么T。例如,假设有一个类型继承自UnusableClass<T>

class Foo : UnusableClass<Foo> { }

现在您可以实例化UnusableClass<Foo>,因为Foo满足约束:

UnusableClass<Foo> f = new UnusableClass<Foo>();

然后T成为的类型,Foo如果您尝试调用,则method需要传递Foo.

于 2015-03-24T09:13:55.220 回答