WPF依賴屬性(續)(1)
阿新 • • 發佈:2018-12-17
原文:
WPF依賴屬性(續)(1)
問題:本一個預設值可以解決的問題,卻用了10000個物件去解決,浪費了記憶體.
思路:為屬性建立一個預設值
思路:提供預設值,如屬性值發生變更,則使用修改的值,但不影響其他物件
程式碼改進如下
之前有寫過幾篇文章,詳細地介紹了依賴屬性的基本使用方法,如果你不想了解其內部實現機制的話,那麼通過那兩篇文章的介紹,足以應付平時的應用了.關於其內部實現,部落格園的周永恆也有人詳細介紹過,還原了依賴屬性的實現.通過閱讀後和閱讀原始碼併為了加深理解,下面則繼續依賴屬性的探討.
屬性記憶體問題
如下程式碼,Name有一個預設的空字串,Test1方法添加了10000個物件,那麼在沒有改變People 的Name屬性情況下,同時也建立了10000個空字串
public class People { private string _name=""; public string Name { get { return _name; } set { _name = value; } } } public class EntityTest { public void Test1() { List<People> list=new List<People>(); for (int i = 0; i < 10000; i++) { list.Add(newPeople()); } } }
問題:本一個預設值可以解決的問題,卻用了10000個物件去解決,浪費了記憶體.
思路:為屬性建立一個預設值
建立屬性預設值
將_name欄位改為靜態private static string _name="";問題:雖然引用同一個記憶體,但當任意修改一個物件的Name屬性時,則全部發生了變更.
思路:提供預設值,如屬性值發生變更,則使用修改的值,但不影響其他物件
程式碼改進如下
public class People { private static string _name=""; private static測試程式碼Dictionary<object, string> list = new Dictionary<object, string>(); public string Name { get { if (list.ContainsKey(this.GetHashCode())) return list[this.GetHashCode()]; return _name; } set { list[this.GetHashCode()] = value; } } }
public static void Test2() { List<People> list = new List<People>(); for (int i = 0; i < 10000; i++) { var entity = new People(); if (i<10) { entity.Name = i.ToString(); } list.Add(entity); } }
依賴物件共享依賴屬性
下面我們來看下WPF元素的依賴屬性,我們可以來比較下兩個不同物件的屬性元資料,返回的結果是相同,也說明了其內部機制也是如此,也是為了節省記憶體.
Object.ReferenceEquals(Button.BackgroundProperty.GetMetadata(button1), Button.BackgroundProperty.GetMetadata(button2));
比較兩個物件的屬性,依然是相同,因為返回的是預設值
Object.ReferenceEquals(button1.Background, button2.Background);
然而為了節省記憶體,真的有必要這麼做嗎?這太麻煩了.
我們知道WPF控制元件繼承而來的屬性有一大片,密密麻麻,當我們佈局的的時候窗體上往往有著很多的元素,如下截圖.如果一個物件以50個屬性(其實遠遠不止)來計算,那麼也是一筆不小的開銷,如果說依賴屬性一開始的動機是為了節省記憶體,實質上其內部功能已經遠遠不是節省記憶體這麼簡單了.下篇繼續