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

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&lt;T&gt; 与可以在此约束中使用的任何其他类一样多。

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

    实例化它? 继承它? 调用它的静态方法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&lt;T&gt;的类型

class Foo : UnusableClass<Foo>  

现在您可以实例化UnusableClass&lt;Foo&gt;,因为Foo 满足约束:

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

然后T 的类型变为Foo,如果您尝试调用method,则需要传递Foo 的实例。

【讨论】:

以上是关于泛型类的基类约束指定类本身的主要内容,如果未能解决你的问题,请参考以下文章

C#学习笔记8

泛型类的 JAXB 序列化失败

C# where用法解析

c# 自定义的一个泛型类可以序列化吗?

从另一个泛型类添加泛型方法约束

Kotlin泛型 ① ( 泛型类 | 泛型参数 | 泛型函数 | 多泛型参数 | 泛型类型约束 )