zoukankan      html  css  js  c++  java
  • c#之Attribute特性的原理

    当我们在Visual Studio添加一个自定义控件时,它都会给我们以下默认的代码。

    [DefaultProperty("Text")]   
        [ToolboxData("<{0}:WebCustomControl1 runat=server></{0}:WebCustomControl1>")]   
        public class WebCustomControl1 : WebControl   
        {   
            [Bindable(true)]   
            [Category("Appearance")]   
            [DefaultValue("")]   
            [Localizable(true)]   
            public string Text   
            {   
                get  
                {   
                    String s = (String)ViewState["Text"];   
                    return ((s == null) ? String.Empty : s);   
                }   
      
                set  
                {   
                    ViewState["Text"] = value;   
                }   
            }   
      
            protected override void RenderContents(HtmlTextWriter output)   
            {   
                output.Write(Text);   
            }   
        }  
    [DefaultProperty("Text")]
        [ToolboxData("<{0}:WebCustomControl1 runat=server></{0}:WebCustomControl1>")]
        public class WebCustomControl1 : WebControl
        {
            [Bindable(true)]
            [Category("Appearance")]
            [DefaultValue("")]
            [Localizable(true)]
            public string Text
            {
                get
                {
                    String s = (String)ViewState["Text"];
                    return ((s == null) ? String.Empty : s);
                }
    
                set
                {
                    ViewState["Text"] = value;
                }
            }
    
            protected override void RenderContents(HtmlTextWriter output)
            {
                output.Write(Text);
            }
        } 
    
    
    

    在这个控件中有个默认的属性"Text",在这个属性有[DefaultValue("")]相应的特性,来给该属性设置默认值。以前一直

    想不明白微软是怎么实现的,直到昨天看了《你必须知道的.Net》中讲“特性”这一章受到了启发。于是我马上去试试,

    还真的可以。废话少说,来看看我的实现方法。

    首先我们先创建一个自己默认值特性SelfDefaultValueAttribute:

    [AttributeUsageAttribute(AttributeTargets.All,   //     可以对任何应用程序元素应用属性       
           AllowMultiple = true,                        //     允许指定多个实例      
           Inherited = false)]                          //     不继承到派生类   
       public  class SelfDefaultValueAttribute : System.Attribute   
       {   
           public SelfDefaultValueAttribute(object defaultVale)   
           {   
               this.AttrValue = defaultVale;   
           }   
      
           public object AttrValue   
           {   
               get;   
               set;   
           }   
       }  
     [AttributeUsageAttribute(AttributeTargets.All,   //     可以对任何应用程序元素应用属性    
            AllowMultiple = true,                        //     允许指定多个实例   
            Inherited = false)]                          //     不继承到派生类
        public  class SelfDefaultValueAttribute : System.Attribute
        {
            public SelfDefaultValueAttribute(object defaultVale)
            {
                this.AttrValue = defaultVale;
            }
    
            public object AttrValue
            {
                get;
                set;
            }
        } 

    接着我们创建一个自己的控件父类SelfControl

    
    
    public  class SelfControl      
     { 
       public SelfControl()           
    	{             
        Type tp = this.GetType();              
        PropertyInfo[] propInfoList = tp.GetProperties();   //获得所有的属性        
          foreach (PropertyInfo p in propInfoList)              
          {  
    	    //获得当前属性的特性                  
          SelfDefaultValueAttribute m = Attribute.GetCustomAttribute(p, typeof (SelfDefaultValueAttribute)) as SelfDefaultValueAttribute;                     
    		//判断该属性是否有特性                   
    		if (m != null)                   
    		{                       
    			//设置默认值                       
    			p.SetValue(this, m.AttrValue, null);                   
    		}                   
    		else                  
    		{                       
    			//设置值为空                       
    			p.SetValue(this, null, null);                   
    		}               
    	  }           
    	}
     
    	[SelfDefaultValue("")]          
    	public virtual string Name          
    	{              
    		get;              
    		set;          
    	}       
    }   
    public class SelfControl    
    {  
        public SelfControl()        
       {            
    	    Type tp = this.GetType();            
    	    PropertyInfo[] propInfoList = tp.GetProperties();   
    	    //获得所有的属性
            foreach (PropertyInfo p in propInfoList)
                {
                    SelfDefaultValueAttribute m = Attribute.GetCustomAttribute(p, typeof
    (SelfDefaultValueAttribute)) as SelfDefaultValueAttribute;                //获得当前属性的特性
    
               /*判断该属性是否有特性*/
                    if (m != null)
                    {
                        /*设置默认值*/
                        p.SetValue(this, m.AttrValue, null);
                    }
                    else
                    {
                        /*设置值为空*/
                        p.SetValue(this, null, null);
                    }
                }
            }
    
           [SelfDefaultValue("")]
           public virtual string Name
           {
               get;
               set;
           }
        } 
    

    这个控件只有一个属性"Name"默认值为空。说明一下的是,在这里我们用到了反射的机制,所以我们要引入空间:
    System.Reflection。

    
    

    现在,我们就可以创建属于自己定义的控件了。

    好了,终于完成了。那我们现在来测试一下。

    public class Myrun   
       {   
           public static void Main(string[] args)   
           {   
               TestSelfControl selfCon = new TestSelfControl();   
               Console.WriteLine("控件宽度:{0}",selfCon.Width);   
               Console.WriteLine("控件高度:{0}", selfCon.Height);   
               Console.WriteLine("控件名字:{0}", selfCon.Name);   
               Console.WriteLine("控件标签:{0}", selfCon.HtmlTag);   
               Console.WriteLine("控件文本:{0}", selfCon.Text);   
      
               Console.ReadLine();   
           }   
       }  
    public class Myrun
       {
           public static void Main(string[] args)
           {
               TestSelfControl selfCon = new TestSelfControl();
               Console.WriteLine("控件宽度:{0}",selfCon.Width);
               Console.WriteLine("控件高度:{0}", selfCon.Height);
               Console.WriteLine("控件名字:{0}", selfCon.Name);
               Console.WriteLine("控件标签:{0}", selfCon.HtmlTag);
               Console.WriteLine("控件文本:{0}", selfCon.Text);
    
               Console.ReadLine();
           }
       } 
    
    最后的结果就是:
    
    view plaincopy to clipboardprint?
    控件宽度:100   
    控件高度:0   
    控件名字:   
    控件标签:   
    控件文本:TestControl  
    控件宽度:100
    控件高度:0
    控件名字:
    控件标签:
    控件文本:TestControl 
    
    
    

    由于我们没给控件的高度设置默认值、高度类型Int,所以高度默认为0;而名字和标签类型为String,所以为空。

  • 相关阅读:
    java实现网络监听
    程序员必须知道FTP命令
    Java进化的尽头
    Oracle逻辑备份与恢复(Data Pump)
    JQuery日期选择器插件date-input
    大型高并发高负载网站的系统架构剖析
    万言万当,不如一默为官之道
    angular.js高级程序设计书本开头配置环境出错,谁能给解答一下
    安装meteor运行基本demo发生错误。
    nodejs 通过 get获取数据修改redis数据
  • 原文地址:https://www.cnblogs.com/chingho/p/1677189.html
Copyright © 2011-2022 走看看