C # 3.0 Auto-Properties - возможно ли добавить пользовательское поведение? - PullRequest
6 голосов
/ 22 сентября 2008

Хотелось бы узнать, есть ли способ добавить пользовательское поведение в методы get / set свойства auto.

Очевидный случай, о котором я могу подумать, - это желание, чтобы каждый метод набора свойств вызывал любые обработчики событий PropertyChanged как часть реализации System.ComponentModel.INotifyPropertyChanged. Это позволило бы классу иметь многочисленные свойства, которые можно наблюдать, где каждое свойство определяется с использованием синтаксиса автоматического свойства.

По сути, мне интересно, есть ли что-то похожее на шаблон get / set или хук post / get / set с областью видимости класса.

(я знаю, что та же самая конечная функциональность может быть легко достигнута несколькими более многословными способами - я просто ненавижу дублирование шаблона)

Ответы [ 6 ]

17 голосов
/ 22 сентября 2008

Нет, вам придется использовать "традиционные" определения свойств для пользовательского поведения.

4 голосов
/ 22 сентября 2008

Нет, вы не можете: свойство auto является ярлыком для явного доступа к приватному полю. например,

public string Name { get; set;} 

является ярлыком для

private string _name;
public string Name { get { return _name; } set { _name = value; } };

Если вы хотите поставить собственную логику, вы должны написать get и установить явно.

2 голосов
/ 22 сентября 2008

Посмотрите на PostSharp . Это AOP-фреймворк для типичной проблемы «этот шаблон кода, который я делаю много раз в день, как я могу его автоматизировать?». С помощью PostSharp вы можете упростить это (например):

public Class1 DoSomething( Class2 first, string text, decimal number ) {
    if ( null == first ) { throw new ArgumentNullException( "first" ); }
    if ( string.IsNullOrEmpty( text ) ) { throw new ArgumentException( "Must be not null and longer than 0.", "text" ) ; }
    if ( number < 15.7m || number > 76.57m ) { throw new OutOfRangeArgumentException( "Minimum is 15.7 and maximum 76.57.", "number"); }

    return new Class1( first.GetSomething( text ), number + text.Lenght );
}

до

    public Class1 DoSomething( [NotNull]Class2 first, [NotNullOrEmpty]string text, [InRange( 15.7, 76.57 )]decimal number ) {
        return new Class1( first.GetSomething( text ), number + text.Lenght );
}

Но это еще не все! :)

1 голос
/ 22 сентября 2008

Наиболее близким решением, которое я могу придумать, является использование вспомогательного метода:

public void SetProperty<T>(string propertyName, ref T field, T value)
 { field = value;
   NotifyPropertyChanged(propertyName);
 }

public Foo MyProperty 
 { get { return _myProperty}
   set { SetProperty("MyProperty",ref _myProperty, value);}
 } Foo _myProperty;
1 голос
/ 22 сентября 2008

Вы можете использовать PostSharp для записи перехватчиков сеттеров. Это и LGPL, и GPLed в зависимости от того, какие части библиотеки вы используете.

1 голос
/ 22 сентября 2008

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

...