2015-10-23 4 views
0

Существует ли метод .net, который определяет, был ли ранее задан данный метод для данного экземпляра объекта?определить, был ли метод уже вызван GetValue .net

Иногда метод геттера свойства имеет побочные эффекты. Например, свойство 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); 
} 

Я посмотрел через класс MethodInfo вернулся из PropertyInfo.GetGetMethod() и ничего не заметил, что там не поможет.

Любые идеи?

В качестве дополнительной заметки, основанной на обратной связи (и спасибо за вшивание!), Я не смог бы изменить существующие объекты, которые я просматриваю.

+0

вы можете настроить счетчик в самом объекте. Я не думаю, что есть такой метод, который вы ищете. – singsuyash

+0

, имеющий свойство getter, которое внезапно начинает создавать дополнительный объект или другие задачи, не является таким хорошим дизайном, я бы сказал ... Почему бы не убедиться, что ваши свойства getters предоставляют только значение и используют интерфейс INotifyPropertyChanged, чтобы указать, что что-то произошло? – Icepickle

+0

Кстати, может быть, Interceptor может помочь в этом месте, просто это будет сильно зависеть от используемой инфраструктуры (IOC?) – Icepickle

ответ

0

Вы можете сделать статическое число в классе, а затем в методе, при первом приращении в 1, если 0 и последующих раз, если 1, то вы знаете, что он уже вызван, и вы можете вернуть -1 или что-то еще.

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, если вы хотите принять все звонки во внимание, независимо от экземпляра класса, который был использован для вызова его.

Обратите внимание, что блокировка может потребоваться, если происходит многопоточность, и у вас есть условное ветвление в зависимости от счетчика.

EDIT

Поскольку класс не может быть изменен (как указано в комментарии), вам необходимо создать класс-оболочку, которая будет агрегировать свой класс и держать счетчик.

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

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

     counter++; 
    } 
}  
+0

Спасибо, но проверяемый класс не может быть изменен. Извините, я не упоминал об этом раньше. – Pedro

+0

@Pedro См. Мое редактирование. – Kapol

1

Поскольку вы заявили несколько раз, что вы не имеете возможность изменять объекты в вопросе, единственным вариантом будет реализовать классы-оболочки для этих типов объектов. В вашем классе-оболочке вы можете выставить все свойства и методы для объектов, о которых идет речь, но вы можете реализовать в своей обертке Getters подсчет ссылок, предложенный в других ответах.

Если вам нужно определить, был ли вызван Getter до того, как вы получили доступ к объекту, я боюсь, что вам не повезло.

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 
    } 
} 
Смежные вопросы