С# 3.0 Auto-Properties — можно ли добавить пользовательское поведение?

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

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

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

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


person morechilli    schedule 22.09.2008    source источник


Ответы (6)


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

person John Sheehan    schedule 22.09.2008

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

public string Name { get; set;} 

это ярлык для

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

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

person stefano m    schedule 22.09.2008

Посмотрите на PostSharp. Это АОП-фреймворк для типичной проблемы «этот шаблон кода я делаю сто раз в день, как я могу его автоматизировать?». Вы можете упростить с помощью 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 );
}

to

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

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

person TcKs    schedule 22.09.2008

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

person Joseph Daigle    schedule 22.09.2008

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

person Justin Rudd    schedule 22.09.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;
person Mark Cidade    schedule 22.09.2008