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,所以为空。

原文地址:https://www.cnblogs.com/chingho/p/1677189.html