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