mardi 26 juin 2018

C#. Force type parameter in generic interface to be the type of the class implementing that interface

Suppose I have the following interface:

interface IFoo<T>{}

I want to know if I can force that any class implementing this interface must provide its own class name as type parameter. Consider IEquatable<T> interface, it is perfectly legal to do:

class Moo:IEquatable<string>{ /*...*/}

Although it does not make any sense right? Suppose now I modify IFoo in the following way:

interface IFoo<T>
{
     void CopyObject(T obj);
}

I do not want to be possible to do the following:

class Foo:IFoo<Boo>{
     public void CopyObject(Boo object){}
}

So far I have tried:

interface IFoo<T> where T: IFoo<T>
{
    void CopyObject(T obj);
}

And it kind of works:

class Foo:IFoo<Boo> { /*implementation*/ } //does not compile!

class Boo { }

But:

class Foo:IFoo<Boo> { /*implementation*/ } //it now copiles =(

class Boo:IFoo<Boo> { /*implementation*/ }

The other way I thinked of was an abstract base class and just crash with a pretty runtime exception if things are not the way I want:

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

    protected abstract void CopyObject(T obj);
}

Now this base class works but then I have problems with existing types that are already inheriting from another type...

Is there any other workaround or design pattern that may help here?

Aucun commentaire:

Enregistrer un commentaire