反射GetProperties应该在特定数据类型中排除不需要的子属性

时间:2014-02-04 07:27:02

标签: c# system.reflection

当然我错过了显而易见的事情。我正在构建一个内部应用程序,我正在反思我们的一些内部dll并在树视图中显示它们

Treeview是按需加载的,每个属性在展开时都会得到子项(如果有的话)。 当孩子是日期时间,字符串,小数等时......然后我再次扩展 我不应该获得字符串或日期时间的所有内部属性,依此类推。它不应该返回任何东西。我尝试了很少的绑定标记但我们没有成功。

我正在使用以下方法,但这还不够好。

  public static PropertyInfo[] GetPropertiesByType(this Type t)
    {
        if (!t.IsPrimitive
            || t != typeof (System.Decimal)
            || t != typeof (System.String)
              || t != typeof(System.DateTime)
            || t != typeof (System.DateTime?))
        {

            return t.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                .OrderBy(p => p.Name).ToArray();
        }
        return new PropertyInfo[0];
    }

我想要的是,在获取属性时,它应该排除所有不相关的内部属性。

EG 客户有订单和订单有OrderedDate.When使用树视图我点击客户和 我点击订单点击订单,点击orderdate时我得到OrderDate我没有属性。我得到“HasValue和value”并扩展价值并得到所有日期时间。

当属性是字符串时,我不应该看到Chars和Length。

任何建议

4 个答案:

答案 0 :(得分:1)

你应该手动检查原始类型并返回一个空数组。你可以在这里查看wuestion的答案How To Test if Type is Primitive

if (t.IsPrimitive || t == typeof(Decimal) || t == typeof(String) || ... )
{
    // Is Primitive, or Decimal, or String
}

所以基本上你可以做到

public static PropertyInfo[] GetPropertiesByType(this Type t)
    {
        if (t.IsPrimitive || t == typeof(Decimal) || t == typeof(String) || ... )
    {
        return //empty array
    }
        return t.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                .OrderBy(p => p.Name).ToArray();
    }

-Update

public static PropertyInfo[] GetPropertiesByType(this Type t)
    {
        if (!t.IsPrimitive
            || t != typeof (System.Decimal)
            || t != typeof (System.String)
            || t != typeof(System.DateTime)
            || t != typeof (System.DateTime?))
        {

            return t.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                .OrderBy(p => p.Name).ToArray();
        }
        else
        return new PropertyInfo[0];
    }

答案 1 :(得分:1)

在扩展之前,您应该检查Type.FullName属性,如果键入它不在命名空间中,则不要展开。

为了详细说明,MSDN中的以下代码说明了FullName的作用:

Type t = typeof(Array);
Console.WriteLine("The full name of the Array type is {0}.", t.FullName);

/* This example produces the following output:

The full name of the Array type is System.Array.
*/

例如,您可以测试FullName是否以“系统”开头。或“微软”。并且不要扩展这些属性。

答案 2 :(得分:0)

可能是:

    public static PropertyInfo[] GetPropertiesByType(this Type t)
    {
        if (!typeof (MyBasePropertyClass).IsAssignableFrom(t))
            return new PropertyInfo[0];

        return t.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                .OrderBy(p => p.Name)
                .ToArray();
    }

其中MyBasePropertyClass是实体的基类。

答案 3 :(得分:0)

if (!t.IsPrimitive
    || t != typeof (System.Decimal)
    || t != typeof (System.String)
    || t != typeof(System.DateTime)
    || t != typeof (System.DateTime?))

应该是

if (!t.IsPrimitive
    && t != typeof (System.Decimal)
    && t != typeof (System.String)
    && t != typeof(System.DateTime)
    && t != typeof (System.DateTime?))

按原样,您的条件将始终评估为true,因为所有类型都不是System.String或不是System.Decimal,并且您将它们与OR运算符组合。