Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to refer to my own type

Tags:

c#

generics

abstract class A<T> where T:A<T>
{
    public event Action<T> Event1;
}

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

Is there a more elegant way to do this? I want stuff (events, etc) in the base class to be able to use the subclass' type.

like image 212
jameszhao00 Avatar asked Feb 23 '23 22:02

jameszhao00


2 Answers

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

like image 190
Eric Lippert Avatar answered Mar 08 '23 17:03

Eric Lippert


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) { ... }

    ...
}
like image 42
James Michael Hare Avatar answered Mar 08 '23 16:03

James Michael Hare