Rud*_*dey 6 .net c# generics casting c#-4.0
我一直忙于C#4.0泛型,现在我基本上想做这样的事情:
public abstract class GenericTree<T> : Tree
where T : Fruit
{
public Tree(IFruitCollection<T> fruits)
: base(fruits) { }
}
Run Code Online (Sandbox Code Playgroud)
基本Tree类如下所示:
public abstract class Tree
{
private IFruitCollection<Fruit> fruits;
public IFruitCollection<Fruit> GetFruits
{
get { return fruits; }
}
public Tree(IFruitCollection<Fruit> fruits)
{
this.fruits = fruits;
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的第一个问题.GenericTree的构造函数无法将泛型集合强制转换为水果集合.我也有GenericTree的实现:
public class AppleTree : GenericTree<Apple>
{
public AppleTree()
: base(new FruitCollection<Apple>) { }
}
Run Code Online (Sandbox Code Playgroud)
这是我的第二个问题.当我使用myAppleTree.GetFruits.Add(...)向AppleTree实例添加水果时,我不仅限于苹果.我被允许添加各种水果.我不想要这个.
我试图通过将其添加到GenericTree来解决该问题:
new public IFruitCollection<T> GetFruits
{
get { return base.GetFruits as IFruitCollection<T>; }
}
Run Code Online (Sandbox Code Playgroud)
但这也是不可能的.它总是以null返回null.当我的第一个问题得到解决时,这可能会得到解决.
IFruitCollection接口如下所示:
public interface IFruitCollection<T> : ICollection<T>
where T : Fruit { ... }
Run Code Online (Sandbox Code Playgroud)
FruitCollection类是Collection类的简单实现.哦,当然,Apple类扩展了Fruit类.
解决方案是使IFruitCollection接口兼容协方差和逆变.但是我该如何实现这一目标呢?"in"或"out"参数关键字是不可能的,因为ICollection接口不允许它.
非常感谢你的帮助!
我想我在尝试 phoog 的解决方法时找到了解决方案。谢谢,噗!
起初我没有给GenericTree他自己的FruitCollection。Mosty 因为基类经常循环访问他自己的集合,例如更新水果。这导致水果不更新,因为它们被添加到 GenericTree 的集合中,而不是添加到基本集合中。
但最终我意识到,铸造这些系列也永远不会成功。
现在,我创建了另一个 FruitCollection 类,它自动向基本 FruitCollection 添加和删除组件,反之亦然。这个解决方案对我来说非常有用!
public FruitCollection<T, U> : FruitCollection<T>
where T : U
where U : Fruit
{
private FruitCollection<U> baseCollection;
public FruitCollection(FruitCollection<U> baseCollection)
: base()
{
this.baseCollection = baseCollection;
// here I added code that throws events whenever the collection is changed
// I used those events to add/remove fruit to the base collection, and vice versa
// see the link below.
...
}
...
}
public class GenericTree<T>: Tree
where T : Fruit
{
private FruitCollection<T> fruits;
// use the new keyword to hide the base collection
new public FruiCollection<T> Fruits
{
get { return fruits; }
}
public GenericTree()
: base()
{
// after hiding the base collection, use base.Fruits to get it
fruits = new FruitCollection<T, Fruit>(base.Fruits);
}
}
Run Code Online (Sandbox Code Playgroud)
这对我有帮助:如何处理添加到列表事件?
| 归档时间: |
|
| 查看次数: |
635 次 |
| 最近记录: |