[英]c# implicit conversion from base class
我有一個這樣的集合類:
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>();
沒有收到錯誤? 請幫忙。 提前致謝。
一個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
(想象一下,如果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#中,不允許將基類明確地轉換為派生類。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.