문제

The following is contrived, but bear with me:

interface Clonable<TSubClass>
{
    TSubClass Clone();
}

How can I restrict TSubClass to be of the implementing type?

i.e only let the implementor do this:

class Dog : Clonable<Dog>
{
    Dog Clone() 
    {
        ....
    }
}

Not this:

class BadDog : Clonable<Rabbit>
{
    Rabbit Clone()
    {
        ....
    }
}
도움이 되었습니까?

해결책

You can't enforce that at compile-time, because .NET generics don't have template specialization or duck typing.

You can, however, include a static constructor (type initializer) that uses reflection to assert the relationship at load time. Ok, C# doesn't allow you to put a static constructor on an interface (even though .NET does allow it), so you would need to use a module initializer or a function you call yourself. Also, you would need to search for types implementing the interface, including types that aren't loaded yet (you can subscribe to the Assembly.Load event to be notified of types loaded in the future).

다른 팁

You can't enforce that, only through convention and documentation....

The convention for me would be to use something like TSelf.

interface ICloneable<TSelf> where TSelf : ICloneable<TSelf> { ... }

Also note that any non-concrete construct that implements or inherits this interface should pass the constraint through...

[Serializable]
abstract class SerializableCloneable<TSelf> : ICloneable<TSelf> 
  where TSelf : SerializableCloneable<TSelf> { ... }

Note: I've implemented this check in NRoles using the convention of calling your self-type parameter S.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top