【问题标题】:c# Generic interface casting [duplicate]c#通用接口转换[重复]
【发布时间】:2017-04-21 07:43:30
【问题描述】:
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

【问题讨论】:

  • 因为类没有差异。查找协变和逆变。这肯定是重复的,我希望有人找到一个匹配的问题来关闭这个。
  • 您在问题中没有 IBusinessModel 或 IBusinessObject 的定义,所以谁知道呢? (但可能是因为虽然User 始终是BusinessObject,但BusinessObject 可能不是User ... 而UserModel 想要User,而不是BusinessObject
  • Stack Overflow 上有数百个问题已经在问您要问的问题:“为什么我不能将我的对象投射到它不是的东西上?”有关最早的示例之一,请参见标记的副本。它包括一些关于为什么你认为你想做的事情实际上不安全的讨论,而不是你的代码应该能够做的事情。

标签: c# generics interface


【解决方案1】:

你应该像这样定义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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-22
    • 2020-01-15
    相关资源
    最近更新 更多