我有一个这样的集合类:
public class SomeDataCollection : List<ISomeData>
{
// some method ...
}
但我不能这样做:
SomeDataCollection someDatas = new List<ISomeData>();
无法隐式将类型
List<ISomeData>
转换为SomeDataCollection
。存在显式转换(您是否错过了演员?)
所以我尝试在SomeDataCollection
集合类中创建隐式转换器:
public static implicit operator SomeDataCollection(List<ISomeData> l)
{
var someDatas = new SomeDataCollection();
someDatas.AddRange(l);
return someDatas;
}
但它说我不能创建这样的转换器:
SomeDataCollection.implicit operator SomeDataCollection(List<ISomeData>)
:不允许在基类之间进行用户定义的转换
当我这样投出时:
SomeDataCollection someDatas = (SomeDataCollection)new List<ISomeData>();
它抛出了一个错误:
System.InvalidCastException:无法将
List<ISomeData>
类型的对象转换为SomeDataCollection
类型。
我该怎么做:
SomeDataCollection someDatas = new List<ISomeData>();
没有收到错误?请帮忙。提前谢谢。
答案 0 :(得分:6)
new List<ISomeData>();
仍然只是List<ISomeData>
。它不是SomeDataCollection
。子类化的要点是子类可以有额外的状态等,但是一个对象(一旦创建)从不改变类型。
不允许在同一层次结构中的类型之间创建运算符,因为这会颠覆常规和预期的转换行为。
你可以简单地使用:
var data = new SomeDataCollection();
但是我应该坦率地补充说,List<T>
的子类很少有用。尤其是,它不会暴露任何有用的virtual
方法,因此您无法调整行为。老实说,我只是使用List<ISomeData>
(并完全删除SomeDataCollection
),除非我有明确的,可证明的目的。然后:我可能封装列表,或继承自Collection<T>
。
您可以随时将该方法添加为扩展方法吗?
public static class Utils {
public static void SomeMethod(this IList<ISomeData> list) {
...
}
}
然后:
var list = new List<ISomeData>();
...
list.SomeMethod();
答案 1 :(得分:2)
首先,为什么要将new List<ISomeData>
写入定义为SomeDataCollection
的变量?
您可能真的想要SomeDataCollection someDatas = new SomeDataCollection();
对于错误消息,第一条错误消息告诉您List<ISomeData>
不是来自SomeDataCollection
,因此您不能使用SomeDataCollection
来处理它,因此你不能把它写成定义为SomeDataCollection
的变量(想象一下,例如SomeDataCollection
中是否有public void someMethod()
,以及稍后你要调用的代码someDatas.someMethod()
)。
第二条错误消息告诉您转换器用于在完全不同的类型之间进行转换,而不是在基于类型和派生类型之间进行转换。否则,你期望获得什么,例如在以下示例中:
SomeDataCollection a = new SomeDataCollection();
List<ISomeData> b = (List<ISomeData>)a;
SomeDataCollection c = (SomeDataCollection)b;
是否应该拨打您的转换器?
基本上你要编写的代码是非常错误的,所以我们需要知道你想要做什么,然后很可能能够告诉你根本问题的解决方案(而不是问题“如何编译此代码”。)
答案 2 :(得分:2)
在SomeDataCollection
中实现构造函数是不是更好?
public SomeDataCollection() : base() { }
这当然可以补充
public SomeDataCollection(IEnumerable<ISomeData> collection)
: base(collection) { }
然后你应该能够像这样初始化你的SomeDataCollection
:
SomeDataCollection someData = new SomeDataCollection();
SomeDataCollection someOtherData =
new SomeDataCollection(collectionOfSomeData);
并且仍然可以访问List<ISomeData>
中的所有公共方法和属性。
答案 3 :(得分:0)
泛型没问题。在C#中,不允许将基类显式转换为派生类。