在 C# 中将动态对象转换为动态类型的数组

本文关键字:动态 类型 数组 转换 对象 | 更新日期: 2023-09-27 18:31:20

我有两种类型:

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

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

我的目标是:
1-迭代我的元素
列表2-确定哪些是 Type1[]array pr type2[] 数组
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# 中将动态对象转换为动态类型的数组

你不能做你想做的事情。坦率地说,您可能也不需要这样做。如果你期待不同的类型,这意味着你将对每种类型做不同的事情。您可以做的是更改 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
    }
}

elementType[] myArrat = (elementType[])myObje

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

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 { ... }

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

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

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