我有一个像这样的集合类:
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>();
没有出现错误?请帮忙。预先感谢。
A
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();
首先,为什么要将
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;
它是否应该调用您的转换器?
基本上,您尝试编写的代码一开始就是非常错误的,因此我们需要知道您想要做什么,然后也许我们能够告诉您根本问题的解决方案(而不是根本问题的解决方案)问题“如何使这段代码编译”)。
在
SomeDataCollection
中实现构造函数不是更好吗?
public SomeDataCollection() : base() { }
这当然可以补充
public SomeDataCollection(IEnumerable<ISomeData> collection)
: base(collection) { }
然后你应该能够像这样初始化你的
SomeDataCollection
:
SomeDataCollection someData = new SomeDataCollection();
SomeDataCollection someOtherData =
new SomeDataCollection(collectionOfSomeData);
并且仍然可以访问
List<ISomeData>
中的所有公共方法和属性。
泛型没有问题。在 C# 中,不允许将基类显式转换为派生类。
我只是无法理解为什么存在从类类型到其任何基类类型的隐式转换。
例如,C# 文档中提供了一个示例...
要有一些课堂要点
public Point
{
int X;
int Y;
point (int x, int y)
{
X = x;
Y = y;
}
}
Now u declare some class Point3D inherited from Point class
public class Point3D:Point
{
int Z;
Point3D (int x, int y, int z) : base (x, y)
{
Z = z;
}
}
现在您可以将某些代码中的某些点声明为...
Point a = new(10, 20);
Point b = new Point3D(10, 20, 30);
这一切是不是造成了一些混乱?我的意思是这里类型安全的含义是什么?实际上,3D 点和 2D 点不是不同的实体吗?不是吗?并且相同类型的 Point 变量可以引用 Point3D 类型对象。
你可以做任何事,没有问题。毕竟,它只是下面的一个指针。所以基本上所有类型的指针或引用在机器上的大小都相同。那么为什么不将任意类型的指针转换为任意类型呢?引用是引用类型或指针......它可以保存任何引用类型。为什么只停留在继承的类基类场景中?
如果你允许这样的事情,那么有人可能会为该代码的未来维护者创建令人困惑的代码,不是吗?
我对所有这些编程都是新手,所以不太了解。所以如果从你的角度来看这是愚蠢的,请原谅我,但我想清除我心中的这种困惑。