【问题标题】: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; 与可以在此约束中使用的任何其他类一样多。

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

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

如果是,怎么做?

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

【问题讨论】:

  • 嗯......闻起来像家庭作业。
  • @JamieKeeling:不,不是真的。我只是对它是否可能感兴趣=)我的朋友完全确定它不是,但我有我的怀疑......
  • 这是递归类型的好模式,如树和图。在几乎所有其他情况下,它都会成为一种反模式,它会使代码复杂化并使其可读性降低。我记得我之前工作中的代码库,到处都在使用它。它仍然让我颤抖。
  • 这不就是F-bounded Polymorphism吗?

标签: c# generics type-parameter generic-constraints


【解决方案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 的实例。

      【讨论】:

        猜你喜欢
        • 2017-01-21
        • 1970-01-01
        • 1970-01-01
        • 2013-08-10
        • 1970-01-01
        • 1970-01-01
        • 2022-10-06
        • 1970-01-01
        相关资源
        最近更新 更多