繁体   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