c# - 为什么这种隐式强制转换是不可能的?
问题描述
给定下面的类和接口,我想知道为什么隐式转换:
ISomeModelAbstract<IBasicModel> x = new ConcreteClass();
是不可能的。我试过了
public interface ISomeModelAbstract<out T> where T: IBasicModel
但后来我不能使用GetById
和GetAll
方法。我感谢任何帮助或提示。谢谢你。
public interface IBasicModel {
string _id { get; set; }
}
public class SomeModel: IBasicModel {
public string _id { get; set; }
/* some other properties! */
}
public interface ISomeModelAbstract<T> where T: IBasicModel
{
bool Save(T model);
T GetById(string id);
IEnumerable<T> GetAll();
bool Update(string id, T model);
bool Delete(string id);
}
public abstract class SomeModelAbstract<T> : ISomeModelAbstract<T> where T : IBasicModel
{
public bool Save(T model)
{
throw new System.NotImplementedException();
}
public T GetById(string id)
{
throw new System.NotImplementedException();
}
public IEnumerable<T> GetAll()
{
throw new System.NotImplementedException();
}
public bool Update(string id, T model)
{
throw new System.NotImplementedException();
}
public bool Delete(string id)
{
throw new System.NotImplementedException();
}
}
public interface IConcreteClass: ISomeModelAbstract<SomeModel> { }
public class ConcreteClass: SomeModelAbstract<SomeModel>, IConcreteClass { }
解决方案
由于协方差问题,这不起作用。考虑这个示例代码。
public class SomeModel2: IBasicModel {
public string _id { get; set; }
/* some other properties! */
}
之后,您可以将 SomeModel2 的某些对象传递给 x 的 Save 方法,显然,这是不行的。
ISomeModelAbstract<IBasicModel> x = new ConcreteClass();
var m = new SomeModel2();
x.Save(m);
为了防止这种情况,您应该隐含地告诉您仅在返回(输出)位置使用泛型类型,而不是在输入中。例如:
public interface ISomeModelAbstract<out T> where T: IBasicModel
不幸的是,在这样做之后,您无法在 ISomeModelAbstract 界面中使用 Save and Update 方法。因为他们在参数(输入)的地方使用了 T。
有关更多信息,请参见以下链接:http ://tomasp.net/blog/variance-explained.aspx/
推荐阅读
- javascript - 试图在 Jest 中模拟一个命名的 commonjs 模块
- javascript - 具有 2 级嵌套的多线图,从 v4 到 v5 的转换问题
- mysql - 来自两个组合查询的数据显示不正确
- amazon-web-services - 我是否需要为未通过基本请求验证的 Amazon API Gateway 请求付费?
- botframework - 如果他/她发现输入的输入不正确,我如何提示用户重新输入上一个瀑布步骤的输入
- java - 尽管我没有从方法返回任何值,但为什么会在我的代码上发生这种情况?
- python - 将列表的元素添加在一起python
- mysql - 确定 n 个日期期间的资源可用性
- java - 如何更新场景根组内的 GridPane
- css - 在 CSS Flex/Grid 中将 `baseline` 值与 `justify-content`、`justify-items` 或 `justify-self` 一起使用是否有意义?