1

所以我有一个名为 VariableSeries 的通用类,一个从它派生的名为 Indicator 的抽象类,然后是实现该抽象类的各种类(我们称它们为指标)。我想要一个指标列表并能够使用它。

public class VariableSeries<T>
{
    protected List<T> Series;
    public int CurrentBar { get; private set; }

    public T this[int index]
    {
        get
        {
            if (index > CurrentBar)
                throw new Exception("Tried to look too far in the past, data does not exist.");

            return Series[CurrentBar - index];
        }
    }
    ...
}

我有一个从 VariableSeries 派生的指标类:

public abstract class Indicator<T> : VariableSeries<T>
{
    ...
}

现在我想要一个各种类型的指标列表。我的第一个想法是只声明一个列表,但这并没有真正起作用。而且我不能只是向它抛出一个接口并强制转换为它,因为我需要使用索引,它利用了泛型类型。

因此,假设我有以下指标(众多指标之一):

public class MovingAverage<T> : Indicator<double>
{
    ...
}

有没有办法做到以下几点:

List<???> Indicators = new List<???>();
Indicators.Add(new MovingAverage<type is provided dynamically>());
do stuff with Indicators[0][0];

也许某种无需指定类型即可转换为泛型类的方式,例如 ((VariableSeries<>)Indicators[0])[0]?

4

4 回答 4

1

???in yourList<???>必须是具体类型。在您的情况下,这种具体类型必须是一个共同共享的基本类型或接口。

您所有的类都共享一个基本类型VariableSeries<T>,但这不是具体/特定的。所以List<VariableSeries<T>>是不可能的。

如果您所有的指示符都使用通用类型double,那么您可以使用List<VariableSeries<double>>,但恐怕情况并非如此。

问题是:你打算如何处理这份清单?遍历它们,然后呢?询问他们的价值?什么价值?哪种类型?双标?一个字符串?编译器不知道!

一种解决方案可能是创建这样的界面:

public interface IVariableSeries
{
    object this[int index] { get; }
}

在您的列表中明确实现此接口VariableSeries<T>并将此接口用作您的具体类型:List<IVariableSeries>.

于 2013-04-24T12:13:51.050 回答
0

您可以使抽象类实现一个接口,该接口具有所有类共有的所有方法,并且没有类型参数。

class VariableSeries<T> : IUntypedInterface

然后,您可以使用 aList<IUntypedInterface>将所有内容放在一起。

于 2013-04-24T12:14:37.353 回答
0

您可以使用反射做一些事情。例如,您可以使用以下命令创建具有动态 T 的 MovingAverage:

Type dynamicType = typeof(int); // or any other, e.g. user selected type
var instance = (dynamic)Activator.CreateInstance(typeof(MovingAverage<>).CreateGenericType(dynamicType));

问题当然是您在编译时不知道实例的类型。因此,您不能对其调用任何方法,也不能对其进行强制转换,当然类型在编译时是未知的。这就是为什么我把它包装成动态的。您可以调用任何方法,它将在后台反映到该类型并查找您调用的方法签名。

MovingAverage<>您可以通过执行检查实例是否为

typeof(MovingAverage<>).Equals(instance.GetType().GetGenericTypeDefinition())

请注意,当实例实际上是 MovingAverage 的派生类型时,这将返回 false。你也可以检查一下,但它有点复杂。

走动态路线在语言中当然是一条危险的道路,否则它非常依赖静态类型检查。您将没有重构支持,并且您必须在运行代码时进行大量测试。一个拼写错误,你的程序就会抛出异常。

另外,我建议您熟悉 .Net 反射。你正在进入一个危险的世界。

于 2013-04-24T12:26:24.257 回答
0

添加一个泛型方法并将类型传递给该方法。此代码将采用通用方法。

列表指标 = new List(); Indicators.Add(new MovingAverage());

于 2013-04-24T13:02:32.310 回答