指定类本身的泛型类的基类约束

Min*_*s97 11 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

如果是的话,怎么样?

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

Ale*_*kiy 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它:

public class BinaryTree:TreeNode<BinaryTree>
{
}
Run Code Online (Sandbox Code Playgroud)


J. *_*een 8

好.

public class Implementation : UnusableClass<Implementation>
{
}
Run Code Online (Sandbox Code Playgroud)

是完全有效的,因此这样做

var unusable = new UnusableClass<Implementation>();
Run Code Online (Sandbox Code Playgroud)

UnusableClass<Implementation>.method(new Implementation());
Run Code Online (Sandbox Code Playgroud)

有效.

所以,是的,它可以通过提供继承类型作为类型参数来实例化,并且类似于对静态方法的调用.例如,它对于树状结构非常有用,在这种结构中,您希望一般性地指定节点具有的子类型,而它本身就是相同的类型.


Sel*_*enç 5

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

它们都是可能的,你就是决定它是什么类型的那个T.例如我们假设有一个类型继承自UnusableClass<T>

class Foo : UnusableClass<Foo> { }
Run Code Online (Sandbox Code Playgroud)

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

UnusableClass<Foo> f = new UnusableClass<Foo>();
Run Code Online (Sandbox Code Playgroud)

然后是T变成的类型,Foo如果你试图调用method你需要传递一个实例Foo.