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