c# - 铸造泛型类型 C#
问题描述
我想有一个接口,它允许我保留泛型类的对象。下面的一些代码和更多解释:
public interface IItem { }
public interface IClass1<T> : IEnumerable<T> { }
public class Item1 : IItem { }
public class Item2 : IItem { }
public class Class1<T> : IClass1<T> where T : class, IItem { }
public class Class2<T> : IClass1<T> where T : class, IItem { }
public class Class : UserControl
{
IClass1<IItem> _item;
public virtual IClass1<IItem> item
{
get
{
return _item;
}
set
{
_item = value;
//then do something...
}
}
public Class2()
{
//few examples what I would like to do
item = new Class1<Item1>();
item = new Class1<Item2>();
item = new Class2<Item1>();
item = new Class2<Item2>();
}
}
问题是 Class2 将作为继承类的基础,我只知道,字段 _item 将保留实现一些通用接口的类的对象(接口继承自 IEnumerable,因此它必须是通用的),我不知道我如何强制字段项接受实现此接口的类的对象,(虽然它们的通用类型可以是 Item1、Item2 等,但它们都实现了 IItem 接口)
解决方案
以下是将您的类重新定义为更易于理解的内容:
public interface IFruit { }
public interface ICollectionOfFruit<T> : IEnumerable<T> { }
public class Apple : IFruit { }
public class Banana : IFruit { }
public class BoxOfFruit<T> : ICollectionOfFruit<T> where T : class, IFruit { public IEnumerator<T> GetEnumerator() { throw new NotImplementedException(); } IEnumerator IEnumerable.GetEnumerator() { throw new NotImplementedException(); } }
public class BagOfFruit<T> : ICollectionOfFruit<T> where T : class, IFruit { public IEnumerator<T> GetEnumerator() { throw new NotImplementedException(); } IEnumerator IEnumerable.GetEnumerator() { throw new NotImplementedException(); } }
public class Class
{
ICollectionOfFruit<IFruit> _item;
public Class()
{
//few examples what I would like to do
_item = new BoxOfFruit<Apple>();
_item = new BoxOfFruit<Banana>();
_item = new BagOfFruit<Apple>();
_item = new BagOfFruit<Banana>();
}
}
您需要了解的是,即使Apple
继承(实现)也不会继承自IFruit
ICollectionOfFruit<Apple>
ICollectionOfFruit<IFruit>
如果ICollectionOfFruit<T>
继承IList<T>
,则转换BoxOfFruit<Apple>
为ICollectionOfFruit<IFruit>
将允许您将 a 添加Banana
到集合中。这会在运行时爆炸。
但是,在您的情况下,ICollectionOfFruit<T>
继承自IEnumerable<T>
因此您可以进行一项简单的更改以使您的代码正常工作:
public interface ICollectionOfFruit<out T> : IEnumerable<T> { }
因为out
这意味着您永远不会尝试将其放入in
您的收藏中IFruit
,因此允许演员表是安全的。
但是,如果您的实际用例允许ICollectionOfFruit<T>
将 aT
作为方法的输入,那么您就不能使用out
.
推荐阅读
- react-native - 我可以将 DJI Mobile SDK 与任何跨平台框架一起使用吗?
- java - 无法从 Firestore 获取项目对象列表
- javascript - 在页面上连续播放随机视频而不重复
- windows - 如何查看windows用户登录?
- macos - 当我的所有表面都在 GPU 上时,为什么 CoreImage 会执行 memcpy
- android - 如何在 Android 和 iOS 中处理 FB 登录撤销或过期
- neo4j - Neo4j 如何使用 apoc.merge.relationship 向我现有的密码添加第二个自定义节点和关系
- javascript - 在数据表中使用下拉菜单无法获取新值
- c# - 问题是使用 GCP 服务将语音转换为文本服务
- powerbi - 在 Power BI 表/矩阵视觉对象中显示/隐藏列