c#用泛型转换接口类型

本文关键字:接口类型 转换 泛型 | 更新日期: 2023-09-27 18:07:37

我有一个类MockRepository实现接口IRepository,我有一个类Technology实现接口IIdentifiable

我想将一个对象从MockRepository<Technology>强制转换为IRepository<IIdentifiable>,并在一些操作完成后再次强制转换。这可能吗?我的代码编译,但当我试图运行它,我得到一个无效的强制转换异常。

c#用泛型转换接口类型

简短的回答是不

如果你有一个接口IMyInterface<T>,那么编译器将为你使用的每种类型的T创建一个新接口,并替换T的所有值

举个例子:

我有一个接口:

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

我有两个类:

public class Foo {}
public class Bar : Foo {}

然后定义以下

public class Orange : IMyInterface<Foo> {}
public class Banana : IMyInterface<Bar> {}

编译器会自动使用特定的命名约定创建两个新接口,我将使用不同的名称来突出它们的不同

public interface RandomInterface {
   Foo Value { get; set; }
}
public interface AlternativeInterface {
   Bar Value { get; set; }
}
public class Orange : RandomInterface {
}
public class Banana : AlternativeInterface {
}

可以看到,RandomInterfaceAlternativeInterface之间没有关系。因此,从RandomInterface继承的类不能强制转换为AlternativeInterface

阅读问题评论后更新

如果您希望将MockRepository传递给期望IRepository的函数,您可以执行以下操作

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

我想你有:

class MockRepository<T> : IRepository<T>  // note: same T
{
}
interface IRepository<out X>  // note: "out" means covariance in X
{
}

然后,因为TechnologyIIdentifiable,协方差给出IRepository<Technology>也是IRepository<IIdentifiable>

所以如果你的IRepository<>接口是(或可以)协变,它应该工作。