c#从基类隐式转换

时间:2012-06-27 07:40:37

标签: c# .net-4.0 implicit-conversion

我有一个这样的集合类:

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>();

没有收到错误?请帮忙。提前谢谢。

4 个答案:

答案 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#中,不允许将基类显式转换为派生类。