• SharpDevelop 属性结构分析


    属性结构位于Core/Property,先看属性系统的工作方式,如图:


    IXmlCovartable接口提供了对象与XML节点互相转换的方法,可以认为是序列化的另一种实现方式。据作者说,这两个方法的实现要比序列化速度快很多。
    IProperties是主接口,应用程序其他部分都通过调用该接口进行工作。它提供了对属性的读写操作,以及一个自身对象的复制方法。

    DefaultProperties是IProperties接口的默认实现方式,其中的几个实现方法确实有点意思。
    这个类其实是个注册工厂,所有属性按需创建,都存在properties这个hashtable中。

    1.先说

    1.先说GetProperty(),这个方法有若干重载,见下:
     1         public object GetProperty(string key, object defaultvalue)
     2         {
     3             if (!properties.ContainsKey(key)) {
     4                 if (defaultvalue != null) {
     5                     properties[key] = defaultvalue;
     6                 }
     7                 return defaultvalue;
     8             }
     9             
    10             object obj = properties[key];
    11             
    12             if (defaultvalue is IXmlConvertable && obj is XmlElement) {
    13                 obj = properties[key] = ((IXmlConvertable)defaultvalue).FromXmlElement((XmlElement)((XmlElement)obj).FirstChild);
    14             }
    15             return obj;
    16         }
    2-8行是在hashtable中找不到key的处理办法:即新建key并设为defaultvalue,同时返回defaultvalue。
    10-15行,如果hashtable中有这个key,那么取出来赋值给obj。如果defaultvalue派生自IXmlCovertable接口同时obj又是XmlElement——13行就难看懂了,真奇怪为什么牛人都喜欢写这么长的语句。把它拆开就是:
                XmlNode node = ((XmlElement)obj).FirstChild;
                XmlElement element 
    = (XmlElement)node;                  //key值应该对应obj的第一个字节点

                IXmlConvertable ixc 
    = (IXmlConvertable)defaultvalue;   //将DefaultValue拆箱为IXmlConvertable

                
    object temp = ixc.FromXmlElement(element);

                obj 
    = properties[key] = temp;

    看到这里,发现defaultvalue在这里不起任何作用,因为FromXmlElement()方法只是创建了一个以element为基础的新的DefaultProperties对象。所以可以简写为
                XmlNode node = ((XmlElement)obj).FirstChild;
                XmlElement element 
    = (XmlElement)node;   //这里element就是obj对象的一个clone

                
    object temp = FromXmlElement(element);

                obj 
    = properties[key] = temp;

    这也就是第13行的意思,既然hashtable中有这个key值,就把它取出来,得到它的第一个子节点,以此为基础重新构造出一个新对象,赋予obj并返回。——这里我不太明白,需要debug到Runtime才会领悟。

    补注:GetProperty有一个Enum版的重载,对我们写程序很有参考价值:
       
            public System.Enum GetProperty(string key, System.Enum defaultvalue)
            {
                
    try {
                    
    return (System.Enum)Enum.Parse(defaultvalue.GetType(), GetProperty(key, (object)defaultvalue).ToString());
                } 
    catch (Exception) {
                    
    return defaultvalue;
                }
            }


    2.SetProperty(string key, object val)
        如果新旧属性值不同,就为该key设置新的属性,并激发事件OnPropertyChanged,这是一个virtual可覆写的事件,不同的场景对该事件有不同的实现,这个事件的自定义参数PropertyEventArgs继承了EventArgs,并随身携带着key/oldValue/newValue。

    3.FromXmlElement():根据XmlElement参数构造出一个新的DefaultProperty对象来,需要辅助函数SetValueFromXmlElement()的配合:

            public virtual object FromXmlElement(XmlElement element)
            {
                DefaultProperties defaultProperties 
    = new DefaultProperties();
                defaultProperties.SetValueFromXmlElement(element);
                
    return defaultProperties;
            }

            
    protected void SetValueFromXmlElement(XmlElement element)
            {
                XmlNodeList nodes 
    = element.ChildNodes;
                
    foreach (XmlElement el in nodes)
                {
                    
    if (el.Name == "Property")
                    {
                        properties[el.Attributes[
    "key"].InnerText] = el.Attributes["value"].InnerText;
                    }
                    
    else if (el.Name == "XmlConvertableProperty")
                    {
                        properties[el.Attributes[
    "key"].InnerText] = el;
                    }
                    
    else
                    {
                        
    throw new UnknownPropertyNodeException(el.Name);
                    }
                }
            }

    SetValueFromXmlElement()方法,需要参考data\options\SharpDevelopProperties.xml文件,以理解一个新的属性对象是如何构造出来的。

    4.ToXmlElement():与FromXmlElement()功能正好相反,不多说了。


  • 相关阅读:
    课程设计第三次实验总结
    课程设计第二次实验总结
    2019春第一次课程设计实验报告
    第十二周作业
    第十一周作业
    第十周作业
    第九周作业
    第八周作业
    第七周作业
    第六周作业
  • 原文地址:https://www.cnblogs.com/Jax/p/830198.html
Copyright © 2020-2023  润新知