最近又要找工作,很多东西要复习。打算写下面试时的复习的东西做成一个系列,先从WPF开始
DependencyProperty
1. The diffirenc between DependencyProperty and CLR Property
The CLR property is just a wrapper around private variables.
The idea of DependencyProperty is to compute the value of property based on external inputs.
Here is a simple prototype of DependyProperty
Public class DependencyProperty
{
Internal static Dictionary<object, DependencyProperty> RegisteredDps=new Dictionary<object,DependencyProperty>();
Internal string Name;
Internal object Value;
Internal object HashCode;
Private DependencyProperty(string name,Type propertyType, Type ownerType, object defaultValue)
{
This.Name=name;
This.Value=defaultValue;
This.HashCode=name.GetHashCode^ownerType.GetHashCode;
}
Public static DependencyProperty Register(string name,Type propertyType, Type ownerType,object defaultValue)
{
DependencyProperty dp=new DependencyProperty(name,propertyType,ownerType,defaultValue);
RegisterdDps.Add(dp.HashCode,dp);
Return dp;
}
}
Public class DependencyObject
{
Public static readonly DependencyProperty NameProperty=DependencyProperty.Register(“name”,typeof(string),typeof(DependencyObject),string.empty);
Public object GetValue(DependencyProperty dp)
{
Return DependencyProperty.RegistedDps[dp.HashCode].Value;
}
Public object SetValue(DependencyProperty dp,object value)
{
DependencyProperty.RegistedDps[dp.HashCode].Value=value;
}
Public string Name
{
get{return GetValue(NameProperty).ToString()}
set{SetValue(NameProperty,value);}
}
}
All DependencyObjects share one DependencyProperty, if one object changed dp value, all the others will change.
So the DependencyObject Add effective conception
Improved DependencyObject with _effectiveValue
Public class DependencyProperty
{
Internal static Dictionary<object, DependencyProperty> RegisteredDps=new Dictionary<object,DependencyProperty>();
Internal string Name;
Internal int Index;
Internal object Value;
Internal object HashCode;
Private static int globalIndex=0;
Private DependencyProperty(string name,Type propertyType, Type ownerType, object defaultValue)
{
This.Name=name;
This.Value=defaultValue;
This.HashCode=name.GetHashCode^ownerType.GetHashCode;
}
Public static DependencyProperty Register(string name,Type propertyType, Type ownerType,object defaultValue)
{
DependencyProperty dp=new DependencyProperty(name,propertyType,ownerType,defaultValue);
globalIndex++;
dp.Index=globalIndex;
RegisterdDps.Add(dp.HashCode,dp);
Return dp;
}
}
Internal struct EffectiveValueEntry
{
Internal int PropertyIndex{get;set;}
Internal object Value{get;set;}
}
Public class DependencyObject
{
Private List<EffectiveValueEntry> effectiveValues=new List<EffectiveValueEntry>();
Public static readonly DependencyProperty NameProperty=DependencyProperty.Register(“name”,typeof(string),typeof(DependencyObject),string.empty);
Public object GetValue(DependencyProperty dp)
{
EffectiveValueEntry effectiveValue=effectiveValues.FirstOrDefault((i)=>i.PropertyIndex=dp.Index);
If(effectiveValue.PropertyIndex!=0)
{
Return effectiveValue.Value;
}
Else
{
Return DependencyProperty.RegistedDps[dp.HashCode].Value;
}
}
Public object SetValue(DependencyProperty dp,object value)
{
EffectiveValueEntry effectiveValue=effectiveValues.FirstOrDefault((i)=>i.PropertyIndex=dp.Index);
If(effectiveValue.PropertyIndex!=0)
{
effectiveValue.Value=value;
}
Else
{
EffectiveValueEntry effectiveValue=new EffectiveValueEntry(){PropertyIndex=dp.Index; Value=value;}
}
}
Public string Name
{
get{return GetValue(NameProperty).ToString()}
set{SetValue(NameProperty,value);}
}
}
Problem: Derived class can override field in parent class
Improved
Public class PropertyMetaData
{
Public Type Type{get;set;};
Public object Value{get;set;}
Public PropertyMetaData(object defaultValue)
{
This.Value=defaultValue;
}
}
Public class DependencyProperty
{
Internal static Dictionary<object, DependencyProperty> RegisteredDps=new Dictionary<object,DependencyProperty>();
Internal string Name;
Internal int Index;
Internal object Value;
Internal object HashCode;
Private static int globalIndex=0;
Private List<PropertyMetaData> metaDataMap=new List<PropertyMetaData>();
Private PropertyMetaData defaultMetaData;
Private DependencyProperty(string name,Type propertyType, Type ownerType, object defaultValue)
{
This.Name=name;
This.Value=defaultValue;
This.HashCode=name.GetHashCode^ownerType.GetHashCode;
PropertyMetaData metadata=new PropertyMetaData(defaultValue){Type=ownerType};
metaDataMap.Add(metaData);
defaultMetaData=metadata;
}
Public static DependencyProperty Register(string name,Type propertyType, Type ownerType,object defaultValue)
{
DependencyProperty dp=new DependencyProperty(name,propertyType,ownerType,defaultValue);
globalIndex++;
dp.Index=globalIndex;
RegisterdDps.Add(dp.HashCode,dp);
Return dp;
}
Public void OverrideMetaData(Type forType,PropertyMetaData metaData)
{
metadata.Type=forType;
metaDataMap.Add(metaData);
}
Public PropertyMetaData GetMetaData(Type type)
{
PropertyMetaData metadata=metaDataMap.FirstOrDefault((i)=>type.isSubClassOf(i.Type));
If(metadata==null)
Return defaultMetaData;
Else
Return metadata;
}
}
Public class DependencyObject
{
Private List<EffectiveValueEntry> effectiveValues=new List<EffectiveValueEntry>();
Public static readonly DependencyProperty NameProperty=DependencyProperty.Register(“name”,typeof(string),typeof(DependencyObject),string.empty);
Public object GetValue(DependencyProperty dp)
{
EffectiveValueEntry effectiveValue=effectiveValues.FirstOrDefault((i)=>i.PropertyIndex=dp.Index);
If(effectiveValue.PropertyIndex!=0)
{
Return effectiveValue.Value;
}
Else
{
Return DependencyProperty.RegistedDps[dp.HashCode].GetMetaData(this.getType()).Value;
}
}
Public object SetValue(DependencyProperty dp,object value)
{
EffectiveValueEntry effectiveValue=effectiveValues.FirstOrDefault((i)=>i.PropertyIndex=dp.Index);
If(effectiveValue.PropertyIndex!=0)
{
effectiveValue.Value=value;
}
Else
{
EffectiveValueEntry effectiveValue=new EffectiveValueEntry(){PropertyIndex=dp.Index; Value=value;}
}
}
Public string Name
{
get{return GetValue(NameProperty).ToString()}
set{SetValue(NameProperty,value);}
}
}
Then we can define a new DependencyObject instance
Public class SubDenpendencyObject:DependencyObject
{
Static SubDependencyObject()
{
NameProperty.OverrideMetaData(typeof(SubDependencyProperty),new PropertyMetaData(“SubName”));
}
}
http://www.cnblogs.com/Zhouyongh/archive/2009/09/10/1564099.html