foreach for dynamic type C# - 动态铸造?反射?

时间:2018-03-10 13:59:50

标签: c# reflection dynamic-programming late-binding

我定义了这样的各种类:

public class Subclass<T> : BaseObject<T>, IObject, IObject<T> { ... }

BaseObject<T>包含我需要的所有功能。 IObject<T>允许在项目之间访问它。 IObject允许创建集合:List<IObject>

BaseObject<T>IObject<T>有一个属性T Value;

所以我有

public class BaseObject<T>  // T is double, int, decimal, long, short, int - in fact anything enumerable
    : IObject, IObject<T>
{
    [...]
    T Value;
    [...]
}

我想解决的问题是如何通过T类型解压缩它。

我想写这个函数,但不知道如何用C#:

public void DoProcessing(List<IObject> objectsToBeProcessed)
{
    foreach(dynamic singleObject in objectsToBeProcessed)
    {
        Type unpackedType = [somehow retrieve the type]
        BaseObject<unpackedType.GetType()> unpackedObject = [do some kind of conversion of singleObject];
        ProcessorClass<unpackedType.GetType()> processor = new ProcessorClass<unpackedType.GetType()>();
        processor.Process(unpackedObject);
    }
}

我发现这很难说出来,但我希望这个解释可以解决这个问题。基本上我在构建List<IObject>时丢失了类型信息,稍后当我将它传递到另一个程序集时我需要它。我想要一个单独的中心DoProcessing方法,然后可以按类型委托给泛型实例。

如何获取类型信息?

我知道泛型需要在编译时知道一种类型。但是这种情况下你只知道运行时的类型。动态关键字允许对集合进行迭代,但我还没有找到在循环中创建位的方法。

或者我应该强制将所有内容强加到doubleBaseObject,然后以某种方式将其强制转换回来?

我对此感到有点失落,觉得我错过了一些明显的东西。欢迎任何想法。

POSTSCRIPT - 澄清

这样做的目的是将代码库分成两个程序集:

  1. BaseObject<T>的程序集允许客户和第三方 写出我们不需要看到的自己的业务逻辑。他们 简单地将BaseObject子类化为他们自己的代码。
  2. IObject&amp; IObject<T>包含通用商家 我们正在创造的逻辑。
  3. 我们需要这种分离,因此客户可以开发自己的代码库,而无需将其提交给我们。他们只是向我们发送List<IObject>的列表,我们完成其余的工作,并在必要时调用它们的子类。

    当然有可能!

    替代地

    任何人都可以建议我所描述的两种装配解决方案的更好的架构解决方案,即客户代码装配中的具体类别。我们的框架程序集中的abstract / interfaces。

    好的,所以我找到了一个更简单的解决方案。通过Reflection进行后期绑定是可行的,但使用我的细微差别对象模型很难实现。

    相反,我已经替换了泛型类型T并实现了一个属性为

    的枚举
    public enum ValueType
    {
        Double,
        Boolean,
        Integer,
        ...
    }
    

    然后我实现了重载的构造函数,将此属性添加到非泛型接口IObject并删除了通用接口IObject<T>,因为它不再需要。

    然后按

    处理doublebool的值
    public double AsDouble();
    public bool AsBoolean();
    public int AsInt();
    ...
    

    在界面中。

    它不优雅或理论上纯粹,但它意味着我不会丢失类型信息,并且可以对待实例。我只是解压缩ValueType并以编程方式选择不同的行为。它还避免使用dynamic关键字,因为所有值都实现为double,因此循环很容易实现。

    从好的方面来说,我已经删除了很多关于泛型的约束,因为它们需要继承层次结构。它变得非常复杂,编译错误变得难以解开。

    从纯粹主义的角度来看,感觉有些不尽如人意,但MongoDB做了类似的事情,这对我来说已经足够好了。

    但我觉得C#是未完成的#34;在这个领域,需要一种更容易向上或向下倾斜的方法。这是一个显而易见的事情。

    也许反射可以以某种方式包裹起来,使其对程序员透明。

    过度工程,实用主义和纯粹主义。这些东西对我来说很重要......

1 个答案:

答案 0 :(得分:1)

这应该足以返回循环内对象的类型:

Type unpackedType = singleObject.GetType();