簡體   English   中英

使用動態方法獲取任意泛型列表

[英]Taking in a list of arbitrary generics in a method using dynamic

假設我有一個方法:

public void update(List<InputSource<dynamic>> inputs);

InputSource是我自己的通用類。 理想情況下,我希望List為泛型任何實例的InputSources列表。 這可行嗎? 換句話說,我希望輸入能夠在同一實例中保存InputSource<double>InputSource<string>InputSource<int>

我嘗試了此方法,但隨后嘗試使用該方法:

InputSource<double> ip = new InputSource<double>();

List<InputSource<dynamic>> inputSources = new List<InputSource<dynamic>>(){ip}; //THIS LINE GIVES ME A COMPILE TIME ERROR

update(inputSources);

標記的行給了我一個編譯時錯誤:

Error   6   The best overloaded Add method 'System.Collections.Generic.List<InputSource<dynamic>>.Add(InputSource<dynamic>)' for the collection initializer has some invalid arguments  
Cannot convert from 'InputSource<double>' to 'InputSource<dynamic>' 

嘗試添加顯式強制轉換:

List<InputSource<dynamic>> inputSources = new List<InputSource<dynamic>>(){(InputSource<dynamic>)inputSource};

給出以下錯誤:

Error   6   Cannot convert type 'InputSource<double>' to 'InputSource<dynamic>'

在這里實現我的目標的正確方法是什么?

也許您可以像這樣更改代碼,所有基於IInputSource InputSource

public interface IInputSource
{ 
}
public class InputSource<T> : IInputSource
{
}

public void update(IList<IInputSource> inputs)
{
    IInputSource ip = new InputSource<double>();
    inputs.Add(ip);
}

使用具有某些約束的泛型來更改update()方法的簽名

public void update<T>(List<InputSource<T>> inputs) where T: 
    IComparable,
    IComparable<T>,
    IConvertible,
    IEquatable<T>

// Check the T for safe if you want

您的編譯錯誤與update()方法無關,調用Add()方法時出現錯誤:

List<InputSource<dynamic>> inputSourceList = new List<InputSource<dynamic>>();
InputSource<double> ipDouble = new InputSource<double>();
inputSourceList.Add(ipDouble); // illegal

即使將InputSource<double>強制轉換為InputSource<dynamic>也是非法的,無論InputSource是協變還是逆變,因為這些差異不適用於值類型(對於感興趣的人,您可以嘗試編譯IEnumerable<object> objs = new List<double>() ):

InputSource<dynamic> ipDynamic = ipDouble; // illegal

您可以使用List<dynamic>List<object>代替List<InputSource<dynamic>>來存儲不同對象的列表。

這是Sky Fang回答的一個變體,您可能會更喜歡。 使用抽象類InputSource代替IInputSource並從中派生InputSource。 然后,您可以執行以下操作:

public
abstract    class   InputSource
{ 

    public      InputSource<T>  As<T>()     { return (InputSource<T>) this; }

    protected
    abstract    Object          getValue();

    public      Object          GetValue()  { return this.getValue(); }

}

public      class   InputSource<T> : InputSource
{

    public
    override    object  getValue()  { return this.GetValue(); }

    public
    new         T       GetValue()  { /* todo: do something interesting here */ throw new NotImplementedException(); }

}

public void update(IList<InputSource> inputs)
{
    inputs.Add(new InputSource<double>());
    inputs.Add(new InputSource<int>());
}

通過界面,一切都是公開的。 使用抽象類,可以定義在通用子類中重寫的受保護的抽象方法和屬性。 您可以在抽象類中創建類型安全的方法,然后在泛型子類中使用類型安全等效項將它們隱藏(例如本示例中的GetValue方法)。

而且,如果仍然要使用IInputSource接口,則可以讓抽象類實現該接口。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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