C# 使用接口约束强制转换泛型类型
我有以下类和接口C# 使用接口约束强制转换泛型类型,c#,generics,interface,casting,C#,Generics,Interface,Casting,我有以下类和接口 public interface IFoo {} public class Foo : IFoo {} public interface IWrapper<T> where T : IFoo {} public class Wrapper<Foo> : IWrapper<Foo> {} 公共接口IFoo{} 公共类Foo:IFoo{} 公共接口iwraper,其中T:IFoo{} 公共类包装器:IWrapper{} 如何将Wrapp
public interface IFoo {}
public class Foo : IFoo {}
public interface IWrapper<T> where T : IFoo {}
public class Wrapper<Foo> : IWrapper<Foo> {}
公共接口IFoo{}
公共类Foo:IFoo{}
公共接口iwraper,其中T:IFoo{}
公共类包装器:IWrapper{}
如何将Wrapper
转换为IWrapper
?使用Cast(InvalidCastException)时引发异常,因为使用as时得到null
谢谢你的帮助
更新
下面是一个更具体的例子:
public interface IUser {}
public class User : IUser {}
public interface IUserRepository<T> where T : IUser {}
public class UserRepository : IUserRepository<User> {}
公共接口IUser{}
公共类用户:IUser{}
公共接口IUserRepository,其中T:IUser{}
公共类UserRepository:IUserRepository{}
现在我需要能够做这样的事情:
UserRepository up = new UserRepository();
IUserRepository<IUser> iup = up as IUserRepository<IUser>;
UserRepository up=newuserrepository();
IUserRepository iup=升级为IUserRepository;
我正在使用.NET4.5。希望这有帮助。Wrapper
需要是Wrapper
。那你就可以投了。它还需要实现接口
下面的演员阵容。。。我认为不能将对象泛型类型参数强制转换为其他类型(即IWrapper
到IWrapper
)
void Main()
{
var foo=new Wrapper();
var t=作为IWrapper的foo;
t、 Dump();
}
公共接口IFoo{}
公共类Foo:IFoo{}
公共接口iwraper,其中T:IFoo{}
公共类包装器:IWrapper{}
包装器
需要是包装器
。那你就可以投了。它还需要实现接口
下面的演员阵容。。。我认为不能将对象泛型类型参数强制转换为其他类型(即IWrapper
到IWrapper
)
void Main()
{
var foo=new Wrapper();
var t=作为IWrapper的foo;
t、 Dump();
}
公共接口IFoo{}
公共类Foo:IFoo{}
公共接口iwraper,其中T:IFoo{}
公共类包装器:IWrapper{}
从您的编辑中,您实际上想要:
public interface IUserRepository<out T> where T : IUser {}
public class UserRepository : IUserRepository<User> {}
如果它出现在输入位置的任何位置,例如方法参数或属性设置器,它将无法编译:
public interface IUserRepository<out T> where T : IUser
{
void Add(T user); //fails to compile
}
公共接口IUser存储库,其中T:IUser
{
void Add(T user);//编译失败
}
从您的编辑中,您实际上想要:
public interface IUserRepository<out T> where T : IUser {}
public class UserRepository : IUserRepository<User> {}
如果它出现在输入位置的任何位置,例如方法参数或属性设置器,它将无法编译:
public interface IUserRepository<out T> where T : IUser
{
void Add(T user); //fails to compile
}
公共接口IUser存储库,其中T:IUser
{
void Add(T user);//编译失败
}
Um,您不能-Wrapper
根本不实现IWrapper
。另外,您是否意识到Wrapper
中的Foo
实际上是一个新的类型参数?真的不清楚你想在这里做什么……是的,我必须回答这个问题,但我有一个说唱者。我仍然不知道如何从包装器中获取IWrapper。好的,我们仍然需要更多信息:a)您使用的是哪个版本的C;b) T
如何在iwraper
中使用?(可能您可以在这里使用通用方差,但我们还不知道。)并且Wrapper
中的Foo
仍然是一个类型参数-您是指Wrapper:IWrapper
和Wrapper
的实例吗?一个完整的例子在这里会有所帮助。我还建议您在可能的情况下使用。当编译器可以告诉您即使不执行您的代码,强制转换也无法工作时,遇到InvalidCastException
是毫无意义的;-)。嗯,你不能-Wrapper
根本没有实现IWrapper
。另外,您是否意识到Wrapper
中的Foo
实际上是一个新的类型参数?真的不清楚你想在这里做什么……是的,我必须回答这个问题,但我有一个说唱者。我仍然不知道如何从包装器中获取IWrapper。好的,我们仍然需要更多信息:a)您使用的是哪个版本的C;b) T
如何在iwraper
中使用?(可能您可以在这里使用通用方差,但我们还不知道。)并且Wrapper
中的Foo
仍然是一个类型参数-您是指Wrapper:IWrapper
和Wrapper
的实例吗?一个完整的例子在这里会有所帮助。我还建议您在可能的情况下使用。当编译器可以告诉您即使不执行您的代码,强制转换也无法工作时,遇到InvalidCastException
是毫无意义的;-)。是的,我必须回答这个问题,但我有一个说唱歌手。我仍然不知道如何从wrapper中获取IWrapper为什么要使用作为
?编译器会将强制转换降级为运行时而不是compiletime。直接赋值更安全,编译器可以告诉您它在compiletime无法工作……是的,我必须回答这个问题,但我有一个实现IWrapper的包装器。我仍然不知道如何从wrapper中获取IWrapper为什么要使用作为
?编译器会将强制转换降级为运行时而不是compiletime。直接赋值会更安全,并使编译器能够告诉您它在compiletime无法工作……虽然从技术上讲您的答案是正确的,但我怀疑IUserRepository
是否可以是协变的-除非它是一个仅获取的存储库(无添加/更新/删除)。@DStanley-请参阅更新。如果这还不够,OP应该添加更多信息。太好了!答案为我指明了正确的方向。现在还不清楚外出工作是为了什么。我现在开始明白了。谢谢@Lee我同意-我只是在评论,所以下一个问题不是“如何向协变接口添加add
方法?”:)虽然从技术上讲您的答案是正确的,但我怀疑IUserRepository
是否可以协变-除非它是一个仅获取的存储库(无添加/更新/删除)。@DStanley-请参阅更新。如果这还不够,OP应该添加更多信息。太好了!答案给了我正确的方向
public interface IUserRepository<out T> where T : IUser
{
void Add(T user); //fails to compile
}