簡體   English   中英

c#從基類隱式轉換

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM