使用 C# 反射读取对象数组的元素

发布于 2024-10-21 15:10:24 字数 2199 浏览 1 评论 0原文

如何使用反射获取 C# 中对象数组的元素和数据类型列表?

场景: 我的 Web 服务 (asmx) 中有一个带有数组参数的方法。使用反射,我正在读取方法参数并循环访问属性。这是我的代码:


示例: 我有一个网络服务 http://localhost/services/myservice.asmx。它有一个方法string GetServiceData(context mycontext)。 context 类具有以下属性

- string name
- Account[] accounts

帐户依次具有

- string acct_name
- string acct_address

我需要动态读取服务以生成以下输出

<GetServiceData>
    <mycontext>
        <name>string</name>
        <accounts>
            <acct_name>string</acct_name>
            <acct_address>string</acct_address>
        </accounts>
    </mycontext>
</GetServiceData>

为此,我动态读取 MethodInfo 并获取所有参数。然后我循环访问参数以获取所有属性和数据类型的列表。 如果属性中有一个数组元素,那么我需要获取该数组元素的所有元素。

解决方案(感谢 Ani)


foreach (MethodInfo method in methods)
{
    sb.Append("<" + method.Name + ">");
    ParametetInfo parameters = method.GetParameters();
    foreach(ParameterInfo parameter in parameters)
    {
        sb.Append("<" + parameter.Name + ">");
        if (IsCustomType(parameter.ParameterType))
        {
           sb.Append(GetProperties(parameter.ParameterType));
        }
        else
        {
            sb.Append(parameter.ParameterType.Name);
        }
        sb.Append("</" + parameter.Name + ">");
    }
    sb.Append("</" + sMethodName + ">");
}

GetProperties() 方法读取类型并实际循环每个属性并将其添加到字符串对象。在这个方法中,我想检查该属性是否是一个数组,然后获取它的所有元素和类型。

public static string GetProperties(Type type)
{
    StringBuilder sb = new StringBuilder();
    foreach(PropertyInfo property in type.GetProperties())
    {
        sb.Append("<" + property.Name + ">");

        if (property.PropertyType.IsArray)
        {
            Type t = property.PropertyType.GetElementType();
            sb.Append(GetProperties(t));
        }
        else
        {
            sb.Append(property.PropertyType.name);
        }
    }
    sb.ToString();
}

How can I get the list of elements and datatypes of an array of an object in c# with reflections?

Scenario:
I have a method with an array parameter in my web service (asmx). Using reflection I am reading the method parameters and loop through the properties. Here is my code:


Example:
I have a webservice http://localhost/services/myservice.asmx. It has a method string GetServiceData(context mycontext).
context class has following properties

- string name
- Account[] accounts

Account in turn has

- string acct_name
- string acct_address

I need to read the service dynamically to generate the following output

<GetServiceData>
    <mycontext>
        <name>string</name>
        <accounts>
            <acct_name>string</acct_name>
            <acct_address>string</acct_address>
        </accounts>
    </mycontext>
</GetServiceData>

To do so I am dynamically reading the MethodInfo and get all the parameters. Then I loop through the parameters to get the list of all the properties and the datatypes.
If there is an array element in the properties then I need to get all the elements of that array element.

Solution (Thanks to Ani)


foreach (MethodInfo method in methods)
{
    sb.Append("<" + method.Name + ">");
    ParametetInfo parameters = method.GetParameters();
    foreach(ParameterInfo parameter in parameters)
    {
        sb.Append("<" + parameter.Name + ">");
        if (IsCustomType(parameter.ParameterType))
        {
           sb.Append(GetProperties(parameter.ParameterType));
        }
        else
        {
            sb.Append(parameter.ParameterType.Name);
        }
        sb.Append("</" + parameter.Name + ">");
    }
    sb.Append("</" + sMethodName + ">");
}

GetProperties() method reads the type and actually loop through each property and add it to string object. In this method I want to check if the property is an array then get all the elements and type for it.

public static string GetProperties(Type type)
{
    StringBuilder sb = new StringBuilder();
    foreach(PropertyInfo property in type.GetProperties())
    {
        sb.Append("<" + property.Name + ">");

        if (property.PropertyType.IsArray)
        {
            Type t = property.PropertyType.GetElementType();
            sb.Append(GetProperties(t));
        }
        else
        {
            sb.Append(property.PropertyType.name);
        }
    }
    sb.ToString();
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

孤独患者 2024-10-28 15:10:24

我认为您正在寻找Type.IsArray属性(指示类型是否为数组)和 Type.GetElementType 方法(获取数组的元素类型等)。请注意,数组的元素类型不一定与数组中每个元素的特定运行时类型相同;多态性可能会发挥作用。

当然,为了简单地获取值,您可以依靠数组协方差:将属性的值(我假设您在某处使用 PropertyInfo.GetValue)转换为 object[] 并像往常一样进行 foreach 操作。

编辑

您的更新非常混乱。如果您已经有一个您认为可能是数组的对象;您不妨这样做:

object obj = ...

object[] array = obj as object[];

if(array != null)
{
   foreach(object item in array)
   {
      ...
   }      
}

看起来您确实将元数据与真实数据混淆了。如果您拥有的只是表示数组类型的 System.Type,那么您实际上无法枚举任何数组。类型

编辑

我想我终于明白你想做什么了。只需使用 Type.GetElementType 获取数组的元素类型,然后获取该类型的属性(递归?)。您可能需要稍微更改一下设计才能获得所需的 XML 输出。 XML 代表层次结构;但你的方法的返回类型只是一个 Dictionary,它是一个平面数据结构。

I think you're for looking for theType.IsArray property (indicates whether a type is an array) and the Type.GetElementType method (gets, amongst other things, the element-type of an array). Do note that the element-type of the array isn't necessarily the same as the specific run-time type of each of the elements of the array; polymorphism could come into play.

Of course, to simply get the values, you can rely on array-covariance: cast the value of the property (I assume you're using PropertyInfo.GetValue somewhere) to an object[] and foreach that as usual.

EDIT:

Your update is quite confusing. If you already have an object that you think might be an array; you might as well do:

object obj = ...

object[] array = obj as object[];

if(array != null)
{
   foreach(object item in array)
   {
      ...
   }      
}

It really appears like you're confusing meta-data with real-data here. You can't actually enumerate any array if all you have is a System.Type that represents an array-type.

EDIT:

I think I've finally understood what you want to do. Just use Type.GetElementType to get the array's element-type, and then get that type's properties (recursively?). You're probably going to change your design a bit to able to get the XML output you want. XML represents a hierarchy; but your method's return-type is just a Dictionary<string, string>, which is a flat data-structure.

秋意浓 2024-10-28 15:10:24

您可以检查 PropertyInfo.PropertyType 属性。像这样:

if (propertyInfo.PropertyType.IsArray)
{
   // Type is an array
}

更新:
如果只想获取数组的属性,可以使用 GetElementType 像这样:

    ...
    //How to check for an array??? and add it to objProp dictionary
    if (property.PropertyType.IsArray)
    {
        //??? how to read all the elements of an array 
        objProp = GetProperties(property.PropertyType.GetElementType());
    }
    ...

You can check the PropertyInfo.PropertyType Property. Like this:

if (propertyInfo.PropertyType.IsArray)
{
   // Type is an array
}

Update:
If you just want to get the properties of the array, you can use GetElementType like this:

    ...
    //How to check for an array??? and add it to objProp dictionary
    if (property.PropertyType.IsArray)
    {
        //??? how to read all the elements of an array 
        objProp = GetProperties(property.PropertyType.GetElementType());
    }
    ...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文