简体   繁体   English

C#3.0自动属性 ​​- 是否可以添加自定义行为?

[英]C# 3.0 Auto-Properties - Is it possible to add custom behaviour?

I would like to know if there is any way to add custom behaviour to the auto property get/set methods. 我想知道是否有任何方法可以为auto属性get / set方法添加自定义行为。

An obvious case I can think of is wanting every set property method to call on any PropertyChanged event handlers as part of a System.ComponentModel.INotifyPropertyChanged implementation. 我能想到的一个明显的例子是希望每个set属性方法都调用任何PropertyChanged事件处理程序作为System.ComponentModel.INotifyPropertyChanged实现的一部分。 This would allow a class to have numerous properties that can be observed, where each property is defined using auto property syntax. 这将允许类具有可以观察到的众多属性,其中每个属性都使用自动属性语法定义。

Basically I'm wondering if there is anything similar to either a get/set template or post get/set hook with class scope. 基本上我想知道是否有任何类似于get / set模板或post类/范围的get / set钩子。

(I know the same end functionality can easily be achieved in slightly more verbose ways - I just hate duplication of a pattern) (我知道可以通过稍微冗长的方式轻松实现相同的最终功能 - 我只是讨厌重复模式)

不,您必须对自定义行为使用“传统”属性定义。

No you cannot : auto property are a shortcut for an explicit accessor to a private field. 不,你不能:auto属性是私有字段的显式访问者的快捷方式。 eg 例如

public string Name { get; set;} 

is a shortcut to 是一个快捷方式

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

If you want to put custom logic you must write get and set explicitly. 如果要放置自定义逻辑,则必须明确写入get和set。

Look to PostSharp . 看看PostSharp It is a AOP framework for typicaly issue "this code pattern I do hunderd time a day, how can I automate it?". 这是一个典型问题的AOP框架“这个代码模式我每天都在做什么,我怎么能自动化呢?”。 You can simplify with PostSharp this ( for example ): 您可以使用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 );
}

But this is not all! 但这并不是全部! :) :)

如果这是一种在开发过程中会重复的行为,您可以为特殊类型的属性创建自定义代码段。

You could consider using PostSharp to write interceptors of setters. 您可以考虑使用PostSharp来编写setter的拦截器。 It is both LGPL and GPLed depending on which pieces of the library you use. 它是LGPL和GPLed,取决于您使用的库的哪些部分。

The closest solution I can think of is using a helper method: 我能想到的最接近的解决方案是使用辅助方法:

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM