Base class constraint on generic class specifying the class itself

后端 未结 3 1749
南旧
南旧 2021-01-17 15:54

Yesterday, I was explaining C#\'s generic constraints to my friends. When demonstrating the where T : CLASSNAME constraint, I whipped up something like this:

相关标签:
3条回答
  • 2021-01-17 16:12

    If any of these is possible, what would the type of T be?

    They are all possible, and you are the one who is gonna determine what is the type of T.For example let's assume there is a type that inherits from UnusableClass<T>

    class Foo : UnusableClass<Foo> { }
    

    Now you can instantiate UnusableClass<Foo> because Foo satisfies the constraint:

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

    Then the type of T become Foo and if you try to call method you need to pass an instance of Foo.

    0 讨论(0)
  • 2021-01-17 16:21

    Well.

    public class Implementation : UnusableClass<Implementation>
    {
    }
    

    is perfectly valid, and as such makes

    var unusable = new UnusableClass<Implementation>();
    

    and

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

    valid.

    So, yes, it can be instantiated by supplying an inheriting type as the type parameter, and similarly with the call to the static method. It's for instance useful for tree-like structures where you want to generically specify the type of children the node has, while it being the same type itself.

    0 讨论(0)
  • 2021-01-17 16:36

    This approach is widely used in Trees and other Graph-like structures. Here you say to compiler, that T has API of UnusableClass. That said, you can implement TreeNode as follows:

    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;
        }
    }
    

    And then use it like this:

    public class BinaryTree:TreeNode<BinaryTree>
    {
    }
    
    0 讨论(0)
提交回复
热议问题