Есть ли способ перехватить сеттеры и геттеры в C #? - PullRequest
31 голосов
/ 17 мая 2011

Как в Ruby, так и в PHP (и, я полагаю, и в других языках) есть несколько служебных методов, которые вызываются при установке свойства. (* instance_variable_set * для Ruby, * __ set * для PHP).

Итак, допустим, у меня есть класс C #, подобный этому:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

Теперь, допустим, что если вызывается какой-либо установщик свойства из класса Person, я хочу сначала вызвать другой метод, а затем продолжить работу с установщиком по умолчанию, и то же самое относится и к установщикам свойств. 1011 *

Возможно ли это?


Edit: Я хочу сделать это без определения отступающего поля.

Ответы [ 11 ]

28 голосов
/ 17 мая 2011

Не обычно;хотя есть несколько опций;

  • наследуется от ContextBoundObject - что делает это разрешающим, но при производительности
  • записывают явное свойство(т. е. с резервным полем) и добавьте вызов служебного метода вручную
  • посмотрите на ткачей времени компиляции, например PostSharp - как правило, путем обнаружения атрибута или аналогичного
  • посмотрите на генераторы кода времени выполнения, предлагаемые некоторыми инструментами DI / IoC (и некоторыми другими инструментами, основанными на «декораторе») - которые либо украшают, либо создают подклассы вашего объекта для добавления дополнительного кода
14 голосов
/ 17 мая 2011

Это можно сделать непосредственно в самом теле свойства, но тогда вам нужно использовать правильное вспомогательное поле вместо автоматически реализуемых свойств .

private string firstName;

public string FirstName 
{ 
  get { return firstName;} 
  set 
  {
    if(check(value))
    {
       firstName = value;
    }
  } 
}

Даже с автоматически внедренными свойствами вы получаете вспомогательное поле - оно генерируется компилятором, и у вас нет прямого доступа к нему.


Edit:

Видя, что вам не нужно вспомогательное поле, у вас есть другие варианты - использование инструмента AOP, такого как PostSharp, может помочь в этом.

4 голосов
/ 17 мая 2011

Вам нужно будет написать свойства полностью, чтобы достичь этого.

2 голосов
/ 17 мая 2011

Вы в состоянии переписать свой класс для реализации интерфейса?Если это так, Перехватчик интерфейса Unity может дать вам то, что вам нужно.Если интерфейс не является опцией, тогда эта ссылка также документирует тип и экземпляры перехватчиков Unity.

2 голосов
/ 17 мая 2011

Я знаю, что на этот вопрос был дан правильный ответ, но я приведу пример, чтобы показать вам синтаксис для достижения того, что вы хотите:

public class Person
{
    private 
    public string FirstName
    {
        get
        {
            return _firstName;
        }
        set
        {
            // see how we can call a method below? or any code for that matter..
            _firstName = SanitizeName(value);
        }
    }
}
1 голос
/ 17 мая 2011

Вы не можете использовать автоматические свойства. Вам нужно будет по-старому придать свойство свойству с помощью вспомогательного поля и вызвать метод вручную.

public class Person
{
    private string _FirstName;
    public string FirstName 
    { 
        get
        {
            return _FirstName;
        }
        set
        {
            SomeMethod();
            _FirstName = value;
        }
    }
    private void SomeMethod()
    {
        //do something
    }

}
1 голос
/ 17 мая 2011

Mocking Framework может сделать это, а также библиотеки IoC, такие как Unity . Единственный другой способ сделать это - использовать переписывание IL (как упоминалось ранее).

1 голос
/ 17 мая 2011

Да, конечно ...

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

пример:

private string firstName;

public string FirstName
{
 get { return firstName; }

 set { doMethod(); firstName = value;}
}
1 голос
/ 17 мая 2011

Не из коробки.Вам нужно будет вставить код в каждый установщик и получатель свойств, либо вручную, либо автоматически с использованием перезаписи IL.

Если вы хотите сделать это вручную, вы больше не можете использовать автоматические свойства.
Если вы хотите сделать это автоматически, взгляните на AOP.

0 голосов
/ 22 марта 2016

Да, вы можете использовать Шаблон оформления декоратора.

...