【问题标题】:convert dynamically object to an array of dynamic type in c#在c#中将动态对象转换为动态类型的数组
【发布时间】:2016-01-21 18:43:55
【问题描述】:

我有两种类型:

    public class Type1
    {
        public string Name { get; set; }
    }

    public class Type2
    {
        public string Name { get; set; }
    }

我有一个元素列表(每个元素都是一个对象类型)。 一些元素可能是一个数组。 (数组可以是 type1[] 或 type2[])

我的目标是:
1-迭代我的元素列表
2-确定哪些是 type1[]array pr type2[] array
3-获取先前数组元素的名称值属性

这就是我所做的:

    foreach (var Myobject in MyList)
    {
        if (myObject.GetType().IsArray)
        {
            var elementType = myObject.GetType().GetElementType()// should me return the element type, ie Type1 or Type2

            //This is where I am stuck, I know that my object is an array but I cannot cast if in type1[] or type2[] array by using elementType
            //The following is not working
            elementType[] myArrat = (elementType[])myObject;

            // And I don't want to hardwrite each case for each possible type like this :
            Type1[] myArrat = (Type1[])myObject;
            Type2[] myArrat = (Type2[])myObject;
            // I want to use the elementType that I got previously

        }
    }

提前感谢您的帮助。

【问题讨论】:

    标签: c# arrays reflection casting


    【解决方案1】:

    你不能做你想做的事。坦率地说,您可能也不需要这样做。如果您期待不同的类型,则意味着您将对每种类型做不同的事情。您可以做的是更改 Type1 和 Type2 以扩展相同的基类并改用基类:

    public class TypeBase 
    {
       public virtual string Name { get; set; }
    }
    
    public class Type1 : TypeBase
    {
    }
    
    public class Type2 : TypeBase
    {
    }
    
    
    foreach (var myobject in MyList)
    {
        if (myObject.GetType().IsArray)
        {
            object[] array = (object[]) myObject;
            TypeBase[] yourArray = array.Cast<TypeBase>();
            //use the properties and methods of TypeBase instead of Type1 and Type2
            //mark the methods and properties in TypeBase as virtual and
            //override them on Type1 and Type2 if needed
        }
    }
    

    【讨论】:

      【解决方案2】:

      elementType[] myArrat = (elementType[])myObje

      elementTypr 不是类型名称,则无法编译。但是,这里几乎没有其他问题。首先,您可能希望将 MyList 元素循环到 flat 数组项:

      private static IEnumerable<object> Flat(IEnumerable<object> items)
      {
          foreach (var item in items)
          {
              var array = item as Array;
              if (array != null)
              {
                  foreach (var arrayItem in array)
                      yield return arrayItem;
              }
              else
                  yield return item;
          }
      }
      

      现在您可以枚举您的列表,而不必担心某些项目是否为数组:

      foreach (var item in Flat(Mylist))
      {
      }
      

      你真正应该做的是将接口(或抽象基类)添加到抽象具体类型:

      interface INamedObject
      {
          string Name { get; set; }
      }
      
      class Type1 : INamedObject { ... }
      class Type2 : INamedObject { ... }
      

      现在您可以在Flat() 返回类型中用INamedObject 替换对象(不要忘记为yield return 添加强制转换)。然后你会像这样使用它:

      foreach (var item in Flat(Mylist))
      {
          item.Name = ""; // It doesn't matter if it's Type1 or Type2!
      }
      

      请注意,如果您不想 (!!!) 添加基类/接口,那么您仍然可以执行类型检查。这是一种非常糟糕的做法,您应该真正考虑更改您的设计以避免这种情况。我的建议是 - 至少 - 不要使用 GetType() 而是直接使用 as 铸造运营商。

      【讨论】:

        猜你喜欢
        • 2020-07-25
        • 2019-06-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多