确定方法是否已被称为GetValue .net

时间:2015-10-23 17:40:13

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

是否有.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类,并没有发现那些有用的东西。

有什么想法吗?

作为一个基于反馈的附加说明(并感谢你加入!),我无法修改我正在检查的现有对象。

4 个答案:

答案 0 :(得分:4)

我认为你实现这一目标的方式过于复杂。您可以为此目的简单地使用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++;
     }
}    

答案 1 :(得分:1)

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

如果您需要确定在访问该对象之前是否已调用Getter,我担心您运气不佳。

答案 2 :(得分:0)

你可以在类中进行静态计数,然后在方法内第一次增加到1,如果为0,则后续时间为1,然后你知道它已经被调用,你可以返回-1或者其他任何东西。

答案 3 :(得分:0)

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

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