使用接口约束强制转换泛型类型

本文关键字:转换 泛型类型 约束 接口 | 更新日期: 2023-09-27 18:25:44

我有以下类和接口

public interface IFoo {}
public class Foo : IFoo {}
public interface IWrapper<T> where T : IFoo {}
public class Wrapper<Foo> : IWrapper<Foo> {}

如何将Wrapper<Foo>强制转换为IWrapper<IFoo>?使用Cast时引发异常(InvalidCastException),因为我在使用as.时获得null

谢谢你的帮助!

更新

这里有一个更具体的例子:

public interface IUser {}
public class User : IUser {}
public interface IUserRepository<T> where T : IUser {}
public class UserRepository : IUserRepository<User> {}

现在我需要能够做这样的事情:

 UserRepository up =  new UserRepository();
 IUserRepository<IUser> iup = up as IUserRepository<IUser>;

我用的是.net 4.5。希望这能有所帮助。

使用接口约束强制转换泛型类型

根据您的编辑,您实际上想要:

public interface IUserRepository<out T> where T : IUser {}
public class UserRepository : IUserRepository<User> {}

那么你可以做:

IUserRepository<IUser> iup = new UserRepository();

注意,只有当类型参数T出现在IUserRepository定义中的所有输出位置时,才能向其添加out修饰符,例如

public interface IUserRepository<out T> where T : IUser
{
    List<T> GetAll();
    T FindById(int userId);
}

如果它出现在输入位置的任何位置,例如方法参数或属性设置器,它将无法编译:

public interface IUserRepository<out T> where T : IUser
{
    void Add(T user);       //fails to compile
}

Wrapper<Foo>需要是Wrapper<IFoo>。然后你应该能够强制转换它。它也需要实现接口。

下面的演员阵容。。。我认为不能将对象泛型类型参数强制转换为其他类型(即IWrapper<Foo>IWrapper<IFoo>)。

void Main()
{
    var foo = new Wrapper();
    var t = foo as IWrapper<IFoo>;
    t.Dump();       
}

public interface IFoo {}
public class Foo : IFoo {}
public interface IWrapper<T> where T : IFoo {}
public class Wrapper : IWrapper<IFoo> {}