Best way to refer to my own type

前端 未结 5 1869
轻奢々
轻奢々 2021-01-03 06:02
abstract class A where T:A
{
    public event Action Event1;
}

class B : A
{
    //has a field called Action Event1;
}
         


        
相关标签:
5条回答
  • 2021-01-03 06:23

    Since A is abstract, you can add abstract methods to A and invoke them from A and B, which will be forced to implement the method, will be the invoker:

    abstract class A<T> where T:A
    {
        public event Action<T> Event1;
        public abstract void Method();
    
        public A(){Method();}
    }
    
    class B : A<B>
    {
        //has a field called Action<B> Event1;
        public void Method(){ //stuff }
    }
    

    On instantiation of B, the base class constructor will call Method() which is only implemented in B, forcing B's instance to be called.

    This allows A to invoke subclass specific methods without requiring A to have specific knowledge of Children. The downside is that ALL children must implement Method or re-abstract it to their own children.

    0 讨论(0)
  • 2021-01-03 06:28

    The pattern you are using does not actually implement the constraint you want. Suppose you want to model "an animal can only be friendly with something of its own kind":

    abstract class Animal<T> where T : Animal<T>
    {
        public abstract void GetFriendly(T t);
    }
    
    class Cat : Animal<Cat>
    {
        public override void GetFriendly(Cat cat) {}
    }
    

    Have we succeeded in implementing the desired constraint? No.

    class EvilDog : Animal<Cat>
    {
        public override void GetFriendly(Cat cat) {}
    }
    

    Now an evil dog can be friendly with any Cat, and not friendly with other evil dogs.

    The type constraint you want is not possible in the C# type system. Try Haskell if you need this sort of constraint enforced by the type system.

    See my article on this subject for more details:

    http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx

    0 讨论(0)
  • 2021-01-03 06:30

    I don't think you need to specify where T:A.

    T will be B when you use class B:A

    This is also known as CRTP or Curiously recurring template pattern and is a known idiom.

    0 讨论(0)
  • 2021-01-03 06:36

    What you have works very well. In fact it's very similar to other .NET interfaces and types where you want the interface implementer to use your type, like:

    public class MyClass : IEqualityComparer<MyClass>
    {
        // From the interface IEqualityComparer
        public bool Equals(MyClass other) { ... }
    
        ...
    }
    
    0 讨论(0)
  • 2021-01-03 06:40

    My most recent question was marked as a duplicate of this one. I totally agree on that matter. So I came here to take a look at the answers and to read Eric's post on that (very interesting indeed). You can not enforce this at compile time with the type system but you can do this at runtime. The way I implemented this is:

    abstract class FooBase<T>
    {
        protected FooBase()
        {
            if (typeof(T) != GetType())
            {
                throw new InvalidOperationException();
            }
        }
    }
    

    By doing this we can plant the seed of an evil dog, but that dog will be aborted at runtime.

    0 讨论(0)
提交回复
热议问题