C#中自动实现的属性

时间:2009-09-15 05:37:44

标签: c# .net

当调用Set时,有没有办法继续使用自动实现的属性,同时仍然会引发更改事件,例如 INotifyPropertyChanged

而不是:

private string _value;
public string Value
{
  get 
  { 
    return this._value;
  }
  set
  {
    this._value = value;
    this.ValueChanged(this,EventArgs.Empty);
  }
}

我可以这样做:

public string Value 
{ 
   get; 
   set 
   { 
     this.ValueChanged(this,EventArgs.Empty); 
   }
}

虽然setter看起来不对,但是可以在没有用后备存储变量填充我的类的情况下这样做吗?

更新:看起来我的懒惰目标没有标准解决方案,我认为最好的解决方案是使用CodeRush或Resharper为我生成所有后备存储。

8 个答案:

答案 0 :(得分:6)

你不能这样做。自动实现的属性的规范非常清楚:

  

自动实施   (自动实现)属性自动化   这种模式。进一步来说,   非抽象财产声明是   允许使用分号访问器   身体。两个访问者必须存在   两者都必须有分号体,   但他们可以有所不同   辅助功能修饰符。当一个   属性是这样指定的,a   支持字段将自动成为   为财产而生成的,以及   将实现访问器以进行读取   来自并写入该支持领域。   支持字段的名称是   编译器生成并且无法访问   用户。

换句话说,他们只能拥有“get;”和“set;”,并且可以使用访问修饰符。

答案 1 :(得分:4)

不,你不能,因为你无权访问为该属性生成的私有字段

答案 2 :(得分:4)

快速Google搜索“inotifypropertychanged自动属性”将引导您访问有关此主题的多篇博文和文章。这是一个:

INotifyPropertyChanged auto wiring or how to get rid of redundant code

答案 3 :(得分:1)

有人问过C#3.0背后的微软团队,他们确实说过会考虑它,请阅读here

在评论中,您将找到更多信息,包括为什么如果您需要更多控制权,以及实现目标的方法,这是一个坏主意。

答案 4 :(得分:1)

您可以使用某些AOP框架,例如PostSharp

但它可以降低性能和建立时间。

答案 5 :(得分:1)

由于我问过这个问题,这个问题实际上已经解决了属性和构建任务: https://github.com/demigor/kindofmagic

答案 6 :(得分:0)

可以使用代理工厂类型生成器完成此行为。我已经在我的开发框架中完成了这个。如果使用System.Reflection.Emit,则可以创建类型代理。 请考虑以下示例:

var a = Proxier<InputType>.CreateInstance(new object[] { }); // object arrays are for different constructors
a.PropertyAccessed += ...

答案 7 :(得分:0)

Fody加载项PropertyChanged执行此操作。就像KindOfMagic一样,Fody使用Mono.Cecil在编译时修改.net程序集的IL。 PropertyChanged文档中列出了以下示例:

你写道:

[ImplementPropertyChanged]
public class Person 
{        
    public string GivenNames { get; set; }
    public string FamilyName { get; set; }

    public string FullName
    {
        get
        {
            return string.Format("{0} {1}", GivenNames, FamilyName);
        }
    }
}

编译的内容:

public class Person : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    string givenNames;
    public string GivenNames
    {
        get { return givenNames; }
        set
        {
            if (value != givenNames)
            {
                givenNames = value;
                OnPropertyChanged("GivenNames");
                OnPropertyChanged("FullName");
            }
        }
    }

    string familyName;
    public string FamilyName
    {
        get { return familyName; }
        set 
        {
            if (value != familyName)
            {
                familyName = value;
                OnPropertyChanged("FamilyName");
                OnPropertyChanged("FullName");
            }
        }
    }

    public string FullName
    {
        get
        {
            return string.Format("{0} {1}", GivenNames, FamilyName);
        }
    }

    public virtual void OnPropertyChanged(string propertyName)
    {
        var propertyChanged = PropertyChanged;
        if (propertyChanged != null)
        {
            propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

wiki包含一些更高级的示例。

可以使用NuGet:

PM> Install-Package PropertyChanged.Fody