【问题标题】:determine if a method has already been called GetValue .net确定方法是否已被调用 GetValue .net
【发布时间】:2015-10-23 17:40:12
【问题描述】:

是否有一个 .net 方法可以确定给定对象实例之前是否调用过给定方法?

有时,属性 getter 方法会产生副作用。例如,如果先前未调用属性 getter,则可能需要创建其他对象并执行其他工作以返回支持字段的值。我不能让这种事情发生。如果之前没有调用过 getter 方法,则不需要该值。

例如...

object item = something;
foreach (PropertyInfo propertyInfoForItem in item.GetProperties(Reflection.BindingFlags.Public)) {
  //Need something to avoid calling this if the property getter method has not been previously been called for this item
  object itemPropertyValue = nothing;
  itemPropertyValue = propertyInfoForItem.GetValue(item, null);
}

我查看了从 PropertyInfo.GetGetMethod() 返回的 MethodInfo 类,但没有发现任何有用的东西。

有什么想法吗?

作为基于反馈的附加说明(感谢您的参与!),我将无法修改我正在检查的现有对象。

【问题讨论】:

  • 您可以在对象本身中设置一个计数器。我不认为你正在寻找这样的方法。
  • 拥有一个突然开始创建额外对象或其他任务的属性获取器不是一个好的设计我会说...为什么不确保您的属性获取器只提供一个值并使用 INotifyPropertyChanged界面表明发生了什么事?
  • 顺便说一句,也许拦截器可以在这个地方提供帮助,但这在很大程度上取决于您使用的框架(IOC?)
  • 感谢大家的反馈。不幸的是,我没有修改现有对象的奢侈。

标签: c# .net reflection system.reflection propertyinfo


【解决方案1】:

我认为您实现这一目标的方式过于复杂。为此,您可以简单地使用 bool 或数字类级别变量。

public class C
{
    private int _counter = 0;
    // private bool _methodCalled = false;

    public void M()
    {
        // check the state of _counter or _methodCalled

        _counter++;
        // _methodCalled = true;
    }
}

如果您想考虑所有调用,则可以创建私有变量 static,而不管用于调用它的类的实例。

请注意,如果有一些多线程正在进行并且您根据计数器有条件分支,则可能需要锁定。

编辑

由于无法修改类(如注释中所述),您需要创建一个包装类来聚合您的类并保存计数器。

public class CWrapper
{
     private int _counter = 0;
     private C _c = new C();

     public M()
     {
         if (_counter == 0)
         {
             _c.M();
         }

         counter++;
     }
}    

【讨论】:

  • 谢谢,但是被检查的类不能被修改。抱歉,我最初没有提到。
【解决方案2】:

由于您多次声明您无法修改相关对象,因此您唯一的选择是为这些对象类型实现包装类。在您的包装器类中,您可以公开相关对象的所有属性和方法,但您可以在包装器 Getters 中实现其他答案中建议的引用计数。

如果您需要在访问对象之前确定是否调用了 Getter,恐怕您不走运。

【讨论】:

    【解决方案3】:

    您可以在类中进行静态计数,然后在方法中第一次递增到 1,如果为 0,后续次数如果为 1,那么您知道它已经被调用,您可以返回 -1 或其他值。

    【讨论】:

      【解决方案4】:

      您可以使用decorator design 模式来执行此操作。

      class Program
      {
          static void Main(string[] args) {
             var hasDoMethodInstance =  new HasDoMethodImpl();
             var hasDoMethodDecoratorInstance = new HasDoMethodDecorator(hasDoMethodInstance);
      
              hasDoMethodDecoratorInstance.Do();
          }
      }
      
      public interface IHasDoMethod
      {
          void Do();
      }
      
      public class HasDoMethodDecorator : IHasDoMethod
      {
          private int counter = 0;
          private readonly IHasDoMethod hasDoMethod;
      
          public HasDoMethodDecorator(IHasDoMethod hasDoMethod) {
              this.hasDoMethod = hasDoMethod;
          }
      
          public void Do() {
              hasDoMethod.Do();
              counter++;
          }
      }
      
      public class HasDoMethodImpl : IHasDoMethod
      {
          public void Do() {
              //Your logic
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-18
        • 1970-01-01
        • 2013-04-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多