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#通用接口铸造

+0

因为类没有差异。查找协变和逆变。这是肯定的重复,我希望有人找到一个匹配的问题来关闭这个问题。 – dasblinkenlight

+1

您在问题中没有IBusinessModel或IBusinessObject的定义,所以谁知道? (但可能是因为虽然'User'总是一个'BusinessObject',一个'BusinessObject'可能不是'User' ...并且'UserModel'想要一个'User',而不是'BusinessObject') – Tibrogargan

+0

有几百个关于Stack Overflow的问题已经问到你在问什么:“为什么我不能把我的对象投到它不是的东西?”查看最早示例中的标记副本。它包括一些讨论,为什么你认为你想要做的事实际上是不安全的,而不是你的代码应该能够做的事情。 –

你应该定义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(); 
  1. IBusinessObject的实现,这是BusinessObject(即User)的子类中,使用的IBusinessObject代替;
  2. 使用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