【问题标题】:How to ignore property when using reflection使用反射时如何忽略属性
【发布时间】:2012-04-12 20:19:07
【问题描述】:

我的班级中有一个公共属性,当给出以下标志时,我应该如何标记它(某些属性)以被忽略

BindingFlags.DeclaredOnly | 
BindingFlags.Instance | 
BindingFlags.NonPublic | 
BindingFlags.Public

我需要使用带有参数的 dll 方法:对象和绑定标志,所以我需要以某种方式标记我的属性以被此方法忽略

【问题讨论】:

  • 在迭代属性时不能跳过它吗?
  • 如果您希望用户能够指定何时忽略,我建议您在 API 中使用参数让用户指定要忽略的属性,或者使用自定义属性来指示它应该被忽略。或者,您是说答案必须遵循这些标志,并且只有这些标志?
  • @Magnus 没有因为我使用来自 dll 的方法:D
  • 不能使用自定义属性吗?
  • @kosnkov:什么方法?什么dll?

标签: c# reflection


【解决方案1】:

我认为您混淆了 BindingFlags 和 CustomAttributes 的角色。 BindingFlags 根据是否为privatestatic等来查找事物。

如果您想忽略消费代码中的某个属性,您需要更改该消费代码以忽略具有与其关联的特定自定义属性的属性。

如果您无权访问使用代码,则没有任何方法可以让它看不到存在的属性。不过,根据代码的编写方式,可能会有一些解决方法。例如,如果代码基于特定类型参数进行搜索,您可以创建一个抽象基类来容纳您希望它关心的所有属性,然后为您的实际实现扩展该类,为您的应用添加一些额外的属性方便。

或者您可以创建一个 DTO 来仅表示您想要传递给您正在调用的方法的属性,然后将适当的属性从您的原始对象复制到该 DTO。

【讨论】:

  • 如果他没有以“给出以下标志时”结束他的问题,我会完全同意。请注意,我对他的问题的评论解决了您正在提出的这一点。另外,嗨:)
  • 鉴于他的旗帜,有一种方法可以让他的旗帜不会产生静电。
  • @StriplingWarrior 我不确定如何通过反射解析属性,但不可能将某些字段标记为“反射!我是特殊领域,不要看着我,继续前进”??如果会给该方法所有可能的绑定标志怎么办?那么没有其他方法仍然可以忽略一些然后改变建模吗??
  • @payo:我的印象是他可能不想改变他的对象的行为(通过将属性设为静态)。
  • @kosnkov:不,通常没有任何方法可以标记要被反射忽略的字段。编写使用反射的方法的人必须为您提供一个 API,该 API 允许您标记要被该框架忽略的属性。例如,大多数序列化/反序列化框架就是这样做的。
【解决方案2】:

在通话期间忽略它的唯一方法是使用Type.FindMembers,但这可能需要更多的工作,而不仅仅是发布过滤它。

【讨论】:

    【解决方案3】:

    我认为自定义属性在这里是合适的。使用该属性装饰您希望忽略的成员,并将您用于检查属性的代码包装在一个例程中,该例程将清除已装饰的项目。

    【讨论】:

      【解决方案4】:

      您可以使用简单的扩展方法来做到这一点:

      public static class ExtensionMethods
      {
          public static PropertyInfo[] GetNonPublicProperties(this Type t) {
              return t.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public).Where(prop => prop.GetAccessors(true).Where(mi => mi.IsPublic == false).Count() != 0).ToArray();
          }
      }
      

      然后只需使用Type.GetNonPublicProperties 就可以了。

      【讨论】:

        【解决方案5】:

        您的标志不会返回静态属性。

        class Foo
        {
          public static int Bar { get; set; }
        }
        

        编辑您已声明不想改变行为。您的 dll 是否采用对象或类型?如果是类型,您可以使用继承来“隐藏”此方法中的属性。

        假设你现在有:

        class Foo
        {
          public int X {get;set;}
          public int Y {get;set;}
        }
        

        您的代码期望Foo 具有XY。如果您的 dll/实用程序采用类型,那么我们可以使 Foo 派生 Bar。假设我们不希望实用程序看到“X”,而只看到“Y”。

        class Bar
        {
          public int Y {get;set;}
        }
        
        class Foo : Bar
        {
          public int X {get;set;}
        }
        

        // 在您的实用程序调用中

        utility.Baz(foo.GetType().BaseType); // <- Base here is Bar, which does not have X
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-04-07
          • 1970-01-01
          • 2017-12-31
          • 1970-01-01
          • 2011-06-26
          相关资源
          最近更新 更多