Daniel Robinson
Daniel Robinson

Reputation: 14898

c# casting to and from interface types with generic types

I have class MockRepository which implements interface IRepository and I have a class Technology which implements interface IIdentifiable.

I want to cast an object from MockRepository<Technology> to IRepository<IIdentifiable> and also cast back again after some operations are complete. Is this possible? my code compiles but when i try to run it i get an invalid cast exception.

Upvotes: 0

Views: 248

Answers (2)

Jeppe Stig Nielsen
Jeppe Stig Nielsen

Reputation: 62012

I take it you have:

class MockRepository<T> : IRepository<T>  // note: same T
{
}

interface IRepository<out X>  // note: "out" means covariance in X
{
}

Then because a Technology is an IIdentifiable, covariance gives that an IRepository<Technology> is also an IRepository<IIdentifiable>.

So if your IRepository<> interface is (or can be made) covariant, it should work.

Upvotes: 0

Bob Vale
Bob Vale

Reputation: 18474

Short answer is no.

If you have an interface IMyInterface<T> then the compiler will create a new interface for each type of T that you use and substitute for all values of T.

To give an example:

I have an interface:

public interface IMyInterface<T> {
   public T Value {get; set;}
}

I have 2 classes:

public class Foo {}

public class Bar : Foo {}

I then define the following

public class Orange : IMyInterface<Foo> {}

public class Banana : IMyInterface<Bar> {}

The compiler will automatically create 2 new interfaces using a specific name convention, I'm going to use different names to highlight that they are different

public interface RandomInterface {
   Foo Value { get; set; }
}

public interface AlternativeInterface {
   Bar Value { get; set; }
}

public class Orange : RandomInterface {
}

public class Banana : AlternativeInterface {
}

As you can see there is no relationship between RandomInterface and AlternativeInterface. So a class inheriting from RandomInterface cannot be cast to AlternativeInterface

UPDATE AFTER READING QUESTION COMMENTS

If you wish to pass MockRepository to a function that expects IRepository you can do the following

 public void MyFunction<T>(IRepository<T> repo) where T: IIdentifiable {
 }

Upvotes: 4

Related Questions