c#通用接口铸造
问题描述:
public abstract class BusinessObject : ObservableObject, IBusinessObject
public abstract class BusinessModel<T> : IBusinessModel<T> where T : IBusinessObject
public class User : BusinessObject
public class UserModel : BusinessModel<User>
为什么我不能将UserModel强制转换为IBusinessModel < IBusinessObject>?c#通用接口铸造
答
基于OP的例子进一步解释:
要得到相同的页面上,让我们先假设我们有一个类和接口这些定义(如一些声明都没有在这个问题提交)
你应该定义IBusinessModel
协这样的:
public interface IBusinessModel<out T>
{
//...
}
然后它工作。
协方差
允许您使用比原先规定的多个派生型。
与往常一样,您可以参考主要reference的完整说明。
基于OP的例子进一步解释:
要得到相同的页面上,让我们先假设我们有一个类和接口这些定义(如一些声明都没有在这个问题提交)
abstract class BusinessObject : ObservableObject, IBusinessObject { }
class ObservableObject { }
interface IBusinessObject { }
abstract class BusinessModel<T> : IBusinessModel<T> where T : IBusinessObject { }
interface IBusinessModel<out T> { } //This change should be made as suggested in my answer
class User : BusinessObject { }
class UserModel : BusinessModel<User> { }
现在,在下面的任务中会发生什么?
IBusinessModel<IBusinessObject> v = new UserModel();
- 的
IBusinessObject
的实现,这是BusinessObject
(即User
)的子类中,使用的IBusinessObject
代替; - 使用
IBusinessModel
(即BusinessModel
)的实现代替IBusinessModel
。
1,因为我们已经说过,我们可以在BusinessModel
个定义中使用的任何IBusinessObject
实例不产生任何问题的情况下:
abstract class BusinessModel<T> : IBusinessModel<T> where T : IBusinessObject { }
2需要IBusinessModel
是逆变的情况下(基于前面引用的定义):
interface IBusinessModel<out T> { } //This change should be made as suggested in my answer
因为类没有差异。查找协变和逆变。这是肯定的重复,我希望有人找到一个匹配的问题来关闭这个问题。 – dasblinkenlight
您在问题中没有IBusinessModel或IBusinessObject的定义,所以谁知道? (但可能是因为虽然'User'总是一个'BusinessObject',一个'BusinessObject'可能不是'User' ...并且'UserModel'想要一个'User',而不是'BusinessObject') – Tibrogargan
有几百个关于Stack Overflow的问题已经问到你在问什么:“为什么我不能把我的对象投到它不是的东西?”查看最早示例中的标记副本。它包括一些讨论,为什么你认为你想要做的事实际上是不安全的,而不是你的代码应该能够做的事情。 –