欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#優(yōu)雅的實現(xiàn)INotifyPropertyChanged接口

 更新時間:2022年08月27日 16:01:01   作者:天方  
這篇文章介紹了C#實現(xiàn)INotifyPropertyChanged接口的方法,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

INotifyPropertyChanged接口在WPF或WinFrom程序中使用還是經(jīng)常用到,常用于通知界面屬性變更。標準寫法如下:

    class NotifyObject : INotifyPropertyChanged
    {
        private int number;
        public int Number
        {
            get { return number; }
            set { number = value; OnPropertyChanged("Number"); }
        }

        private string text;
        public string Text
        {
            get { return text; }
            set { text = value; OnPropertyChanged("Text"); }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName = "")
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

這種寫法的兩個問題是

  • 對屬性名使用了字符串硬編碼,容易寫錯,也不方便重構(gòu)
  • 冗余代碼,如果屬性較多的時候?qū)懙孟胪?/li>

 我在博客文章使用CallerMemberName簡化InotifyPropertyChanged的實現(xiàn)中介紹了通過Caller Information解決屬性名稱字符串硬編碼的問題。但是仍然不能解決冗余代碼的問題。對于第二個問題,往往是通過AOP的方式實現(xiàn),一般的實現(xiàn)方式有兩種:

  • 通過代理對象封裝
  • 通過編譯期間代碼注入的方式實現(xiàn)

我增在項目中使用過DynamicObject封裝來實現(xiàn)過,主要原理是用實現(xiàn)一個PocoNotifyWrapper的DynamicObject類,托管其屬性的讀寫動作,并附加IntofyPropertyChanged接口實現(xiàn)。

這種方式是動態(tài)的AOP了,是一個通用的方式,并且擴展性比較器,可以通過繼承PocoNotifyWrapper來實現(xiàn)多態(tài)。用它做ViewMode層還是比較方便。

不過一個不大好的地方是DynamicObject是丟失了屬性類型信息的,有時綁定時會出錯(如將一個TextBox的Text綁定到一個封裝后的Int類型對象時會不進行自動類型轉(zhuǎn)換)。要解決它還需要實現(xiàn)一些其它的接口,實現(xiàn)起來還是有些復(fù)雜的,并且項目進度比較緊張,沒有太多時間來完善它。

另外一種方式是通過編譯期間代碼注入方式來實現(xiàn):

最開始見的是PostSharp的一個實現(xiàn): http://doc.postsharp.net/inotifypropertychanged-add。不過PostSharp是收費的,后來也逐漸由了許多其它的免費的解決方案。本文這里介紹的是一個開源的解決方案:Fody

使用它非常簡單,首先通過Nuget安裝庫:PM> Install-Package PropertyChanged.Fody。然后在需要實現(xiàn)屬性通知的類上加一個[ImplementPropertyChanged]即可:

  [ImplementPropertyChanged]
  public class Person
  {

    public string GivenNames { get; set; }
    public string FamilyName { get; set; }

    public string FullName => 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));
        }
    }
}

基本上對代碼沒有注入,不需要安裝插件,也不影響調(diào)試,實現(xiàn)非常簡單,非常方便。

需要注意的是,如果實現(xiàn)了INotifyPropertyChanged接口,即使沒有[ImplementPropertyChanged]標記,默認也會注入。

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請查看下面相關(guān)鏈接

相關(guān)文章

最新評論