【问题标题】:Reflection GetProperties should exclude unwanted children properties on certain datatype反射 GetProperties 应排除某些数据类型上不需要的子属性
【发布时间】:2014-02-05 02:43:03
【问题描述】:

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

Treeview 是按需加载的,对于每个属性,在展开时我会获取子项(如果有)。 当孩子是日期时间,字符串,十进制等时。然后我再次展开 我不应该得到字符串或日期时间等的所有内部属性。它不应该返回任何东西。我尝试了几个 bindingFlags 但我们没有成功。

我正在使用下面的方法,但是还不够好。

  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。使用树视图时,我点击客户和 我在订单上点击订单,在点击订单日期时我得到 OrderDate 我应该没有任何属性。我得到“HasValue and value”并展开值并获取所有日期时间的东西。

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

任何建议

【问题讨论】:

  • 所以您实际上想要排除任何属于本机 CLR 类型的属性?字符串(String)、整数(Int32)等?
  • @Abhinav 是的,这是正确的

标签: c# system.reflection


【解决方案1】:

您应该手动检查原始类型并返回一个空数组。你可以在这里查看问题的答案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();
    }

-更新

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];
    }

【讨论】:

  • 感谢您的回复尝试了以下方法,但仍然无法正常工作。查看更新的问题代码 sn-p
  • 您是否尝试过我刚刚添加的代码示例,它与您所做的并不完全相同
  • 是的,我做到了。唯一的区别和错字是 !t.IsPrimitive
  • 现在仍在填充什么类型的成员?
【解决方案2】:

在扩展之前,您应该检查 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 是否以“System”开头。或“微软”。并且不要扩展这些属性。

【讨论】:

  • 您好,感谢您的宝贵时间。你能详细说明一下,我不明白吗
【解决方案3】:
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?))

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

【讨论】:

  • 嗨,这似乎有效!您如何将可为空的布尔值检测为布尔值?似乎没有被检测到。
  • @user231465 如果您从对 GetType() 的调用中获取参数 Type t,则不需要检测可为空的 bool(在 bool 上调用 GetType()?应该返回 typeof(bool) )。见msdn.microsoft.com/en-us/library/ms366789.aspx。如果这解决了您的问题,请接受答案。
  • @DerekJS 求名? :)
  • @Bogdan 我昨天刚刚得到足够的评论,所以暂时,是的。
【解决方案4】:

可能是:

    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 是实体的基类。

【讨论】:

    猜你喜欢
    • 2011-01-04
    • 2021-10-13
    • 1970-01-01
    • 2018-01-20
    • 1970-01-01
    • 1970-01-01
    • 2018-03-14
    • 1970-01-01
    • 2020-01-28
    相关资源
    最近更新 更多