国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

WPF依賴屬性

2019-11-14 15:47:59
字體:
來源:轉載
供稿:網友
    我們知道,在我們的C#中 有屬性這個概念,也有字段這個概念。關于字段,我們知道當不被static修飾的時候,會在內存中真正的去申請相應的內存空間。每個字段都會有一塊自己的空間。而屬性是什么? 屬性本身其實是方法,只是C#提供了語法糖是的寫法變的更簡單而已。
比如 我們的類如下
 public class Person
    {
        PRivate string name;
        private string sex;
        public int age;
        public string Name
        {
            get { return name; }
            set { name = value ; }
        }
        public string Email
        {
            get;
            set;
        }     
    }
對應的IL如下
我們可以清晰的看到 Email 這個屬性 本質上只是 get_Email和set_Email這兩個方法,并且我們會發現,當我們沒有手動提供直接的字段作為背后的支持的話, 他會自動生成相關的“BackingField”--背后支持的字段,來做支持,有就是說也會申請相應的內存空間來存放 相應的字段。比如 Email 屬性就生成的是 <Email>k_BackingField 這樣的字段而已,連名字都起的相當貼切。
 
這樣 我們的屬性和字段就應該相當清楚了。 概括起來就是 屬性只是方法的簡寫(語法糖),背后支持仍然是真實存在的字段,需要真正的內存空間申請。
 
那么,好,在標準的屬性系統上,如果我們的一個類有100個屬性,那么創建這樣的一個實例,實際上屬性共需要100個內存空間,如果創建 100個這樣的對象,就需要100*100個空間。這樣子會有什么不好嗎? 這個例子還不夠詳細,不夠貼切,可能還感受不到。
舉個更貼切的例子。
我們的一個TextBox 類可能有100個屬性,但其中真正經常會使用的也許就只有Text這一個屬性。那其他99個屬性也是要申請空間的。
如果我們使用了100個TextBox對象,每個對象只是Text屬性不同 其他的所有屬性,都完全一樣,你會不會覺得 為這所有的100個控件的不常用的99個屬性 一共申請99*100個空間 有點浪費?我明知道你們是一模一樣 保持一致的,卻還只能給你申請空間來存一模一樣的東西,是有那么點浪費。 不過現在電腦內存好像都挺大的,你可以懶得去管這些什么內存不內存的,(現實確實不去考慮這些)。但先別急,我們只是為了講清楚知識點。也就是說,現有的屬性系統 在某些情況下(大量實例,屬性值相同),對于內存的開銷有點大。
  我們來手動簡略模擬一下WPF的依賴屬性系統  如下
public class DependencyProperty    {        public static Dictionary<Object, DependencyProperty> Dic = new Dictionary<object, DependencyProperty>();        public string name;        public object defaultvalue;        public object Hashcode;        private DependencyProperty(string name, object value, Type propType, Type owenerType)        {            this.name = name;            this.defaultvalue = value;            this.Hashcode = propType.GetHashCode() ^ owenerType.GetHashCode();        }        public static DependencyProperty Register(string name, object value, Type propType, Type owenerType)        {            DependencyProperty p = new DependencyProperty(name, value, propType, owenerType);            Dic.Add(p.Hashcode, p);            return p;        }    }
  public class DependencyObject    {        public static DependencyProperty NameProperty = DependencyProperty.Register("Name", "shenwei", typeof(string), typeof(DependencyObject));        public static DependencyProperty AgeProperty = DependencyProperty.Register("Age", 23, typeof(int), typeof(DependencyObject));        public Object GetValue(DependencyProperty d)        {            return DependencyProperty.Dic[d.Hashcode];        }        public void SetValue(DependencyProperty d, object value)        {            DependencyProperty.Dic[d.Hashcode].defaultvalue = value;    //現在的情況是  設置的屬性值是默認值。 那接下來所有實例的這個屬性的默認值都應該是這個。但是現在的代碼 實際上一個實例修改 ,所有的實例都會修改。 那我們這邊的setValue就不能這么寫。我們還需要一個單獨服務于 實例的字典。        }    }

 這個是我們模擬的第一步,目前我們所做的就是建立一個靜態字典,然后向其中插入數據
 插入的值時一個 dependencyProperty對象,插入的鍵很有意思,是由DependencyProperty本身的 數據類型以及擁有這個屬性的類的類型共同決定
 由這兩者本身的hashcode異或組成了這個依賴屬性的hashcode 作為鍵值存儲在靜態字典中。
 但是這樣子,一個實例的屬性弱發生變化,這個類的所有實例的這個以來屬性都會發生變化,很顯然這是 荒唐的。 這邊只 是針對這個屬性的默認值的情況。

 在DependencyObject里面添加了一個實例字典,來存儲實例的屬性值,避免了一個實例屬性改,所有都改的尷尬。

 public class DependencyObject    {        public static DependencyProperty NameProperty = DependencyProperty.Register("Name", typeof(string), typeof(DependencyObject), "shenwei");        public static DependencyProperty AgeProperty = DependencyProperty.Register("Age", typeof(int), typeof(DependencyObject), 23);        //小旅行包        private Dictionary<object, object> Dic_for_instance_propertyValue = new Dictionary<object, object>();    //鍵值就采用的DependencyProperty的鍵值,因為這個實例字典是屬于實例自己的,所以無需擔心重復。        public object GetValue(DependencyProperty p)        {            if (Dic_for_instance_propertyValue.ContainsKey(p.hashcode))            {                return Dic_for_instance_propertyValue[p.hashcode];   //返回實例的屬性具體值            }            return DependencyProperty.Dic_Dps[p.hashcode].property_default_value;  //返回屬性默認值        }        public void SetValue(DependencyProperty p, object pro_value)        {            Dic_for_instance_propertyValue[p.hashcode] = pro_value;        }        public string Name        {            get            {                return this.GetValue(DependencyObject.NameProperty).ToString();            }            set            {                SetValue(NameProperty, value);            }        }        public int Age        {            get { return (Int32)(this.GetValue(DependencyObject.AgeProperty)); }            set { SetValue(AgeProperty, value); }        }    }

 如果 依賴屬性系統單單只是為了 優化一下內存,那其實個人認為 并沒有什么必要這么大費周章,所以依賴屬性的功能并不是體現在此,而是體現在屬性更改通知等。
我們現在添加屬性更改通知功能

    public delegate void PropertyChangedCallBack();    public class PropertyMetaData    {        public PropertyChangedCallBack PropertyChanged;        public PropertyMetaData(PropertyChangedCallBack para)        {            PropertyChanged = para;        }    }

然后,與DependencyProperty相結合,就可以實現屬性更改通知功能了。詳細我們也就不鋪開陳述了。

借助于依賴屬性,WPF構建了強大的屬性系統,可以支持數據綁定、樣式、附加屬性等功能。我們手動簡單的模仿了一下以來屬性系統的大致實現,當然,具體肯定和WPF的實現還有不小的偏差。

 

 

 
 
 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 宁城县| 石河子市| 宁城县| 额尔古纳市| 蒲城县| 惠水县| 宜黄县| 阳城县| 梁平县| 盘山县| 贵溪市| 两当县| 冀州市| 靖江市| 绥化市| 成武县| 深圳市| 通化县| 尉犁县| 运城市| 和龙市| 兴安县| 莱芜市| 鱼台县| 古田县| 岳普湖县| 洪江市| 温宿县| 博客| 洮南市| 嘉荫县| 隆子县| 奉化市| 杭州市| 清水县| 江门市| 灵台县| 华容县| 都江堰市| 德惠市| 建始县|