Ari
Ari

Reputation: 3127

Conversion from template class

I have class MyClass<T> where T is some interface:

class MyClass<T> where T: IMyInterface

I wrote several classes which extend MyClass using some implementation of IMyInterface, for example:

class MySecondClass : MyClass<MyInterfaceImplementation>

Why assignement MySecondClass instance to variable with type MyClass<IMyInterface> is not allowed?

MyClass<IMyInterface> x = new MySecondClass()

When I add implicit conversion:

public static implicit operator MyClass<IMyInterface>(MySecondClass c) {
    return c;
}

it starts working.

Upvotes: 2

Views: 578

Answers (3)

Paolo Tedesco
Paolo Tedesco

Reputation: 57192

To do what you want, you should declare that the type parameter T is covariant using the out keyword (see Covariance and Contravariance in Generics on MSDN).
You would need to modify your code a little, as covariance and contravariance can only be defined on interfaces:

interface IMyInterface { 
}

// note that this one is an interface now
interface IMyClass<out T> where T : IMyInterface { 
}

class MyInterfaceImplementation : IMyInterface { 
}

class MySecondClass : IMyClass<MyInterfaceImplementation> { 
}

class Program {
    static void Main(string[] args) {
        IMyClass<IMyInterface> x = new MySecondClass();
    }
}

Upvotes: 2

Pavel
Pavel

Reputation: 554

MyClass<IMyInterface> and MySecondClass two different classes and compiler cannot implicitly convert object of one type to another.

And even more these two classes have only System.Object as common base class

Upvotes: 1

jkokorian
jkokorian

Reputation: 3095

That is because of the nature of generic classes (templates in c++ lingo) and by design.

For example:

MyClass<object> o = new MyClass<string>();

will also fail to compile. Generic classes are no descendants from each other just because their generic types are. They really are different classes that have no relation to each other in an object oriented sense.

Upvotes: 0

Related Questions