【发布时间】:2014-01-05 10:55:20
【问题描述】:
我有 2 个供客户使用的公共接口
public interface IASet<T> where T : IItem {
HashSet<T> Collection { get; set; }
}
public interface IItem {
string Name { get; set; }
}
这个想法是让客户端通过这个对象来访问数据:
IASet<IItem> aset = GetIt();
foreach(IItem i in aset.Collection)
Console.WriteLine(i.Name);
具体实现如下:
private class ASet : IASet<OneItem>{
public HashSet<OneItem> Collection { get; set; }
}
private class OneItem : IItem{
public string Name { get; set; }
}
最后是生成对象的函数:
public static IASet<IItem> GetIt()
{
ASet a = new ASet();
a.Collection = new HashSet<OneItem>();
a.Collection.Add(new OneItem() { Name = "one" });
a.Collection.Add(new OneItem() { Name = "two" });
//for test :
foreach (IItem i in a.Collection)
{
Console.WriteLine(i.Name);
}
/*Error 1 Cannot implicitly convert type 'ConsoleApplication2.Program.ASet'
* to 'ConsoleApplication2.IASet<ConsoleApplication2.IItem>'. An explicit
* conversion exists (are you missing a cast?)
*/
//return a;
/*Unable to cast object of type 'ASet' to type
* 'ConsoleApplication2.IASet`1[ConsoleApplication2.IItem]'.
*/
return (IASet<IItem>)a;
}
因为我的真实代码没有这个简单,我不能把ASet : IASet<OneItem>改成ASet<T> : IASet<T>这样的东西
能否请您解释一下为什么我不能这样做,以及一些解决问题的建议?
谢谢
【问题讨论】:
-
因为 IASet 上的
T是不变的。它是这样声明的,IASet<out T>,它会起作用 - 但你不能这样做,因为 HashSet 不会接受它。 -
我相信这只有在
IASet的泛型类型被定义为out模板参数时才有效。请参阅msdn.microsoft.com/en-us/library/dd469487.aspx 没有什么可以阻止某人将不同类别的IItem对象添加到集合中的集合中。
标签: c# generics collections interface variance