2012-06-27 72 views
7

我有一个集合类,像这样:C#的隐式转换

public class SomeDataCollection : List<ISomeData> 
{ 
    // some method ... 
} 

,但我不能做到这一点:

SomeDataCollection someDatas = new List<ISomeData>(); 

无法隐含转换型List<ISomeData>SomeDataCollection 。一个显式转换存在(是否缺少强制转换?)

,所以我尝试创建内部SomeDataCollection集合类隐式coverter:

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

可能dupplicate:http://stackoverflow.com/questions/3401084/user-defined-conversion-operator-from-base-class – albertjan

回答

6

A new List<ISomeData>();仍然只是一个List<ISomeData>。这不是SomeDataCollection。子类化的要点是子类可以有额外的状态等,但一个对象(一旦创建)从不更改类型。

您不允许在同一层次结构中的类型之间创建运算符,因为这会破坏通常和预期的转换行为。

你可以简单地使用:

var data = new SomeDataCollection(); 

但是我要补充一点,坦率地说是子类List<T>很少有用。同样重要的是,它没有公开任何有用的方法,所以你不能调整行为。我会诚实地使用List<ISomeData>(并且完全删除SomeDataCollection),除非我有明确的目的。然后:我可能要么封装的列表,要么继承Collection<T>

您可以随时添加方法作为扩展方法?

public static class Utils { 
    public static void SomeMethod(this IList<ISomeData> list) { 
     ... 
    } 
} 

则:

var list = new List<ISomeData>(); 
... 
list.SomeMethod(); 
+0

我实际上并没有在'SomeDataCollection'中放一个新实例化的'List '那只是一个样本:P。我使用'List '因为它已经有一些函数用于添加,删除等对象,并且在我的'SomeDataCollection'类中还有一些额外的方法和属性,它们只是为了列出'List '类型。 –

+1

@约翰国际海事组织有一些东西都是列表*和*有自己的国家是一个错误;很多框架/库*讨厌* - 绑定,序列化,物化等等。你应该有一个对象,它拥有*这些属性,哪些属性也有* IList Items {get;}' –

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

是不是更好地执行在SomeDataCollection构造?

public SomeDataCollection() : base() { } 

这当然可以与

public SomeDataCollection(IEnumerable<ISomeData> collection) 
    : base(collection) { } 

补充然后,你应该能够初始化SomeDataCollection这样,而不是:

SomeDataCollection someData = new SomeDataCollection(); 
SomeDataCollection someOtherData = 
    new SomeDataCollection(collectionOfSomeData); 

,仍然可以访问所有的公共方法以及List<ISomeData>的房产。

0

它对泛型没有问题。在C#中,您不允许将基类明确地转换为派生类。