属性是.NET Framework最有用的的特性之一,研究它们需要花费大量时间,但是掌握了之后,对我们开发是非常有帮助的

讲之前,大家要知道.net framework属性和C#属性是有区别的哦,不要搞错了.

 

下面我们讲讲它的概念

.net framework属性是一个包含程序集中其他数据的类,这些数据涉及到程序集或程序集中的任何类型.

它的格式大家肯定也不陌生,在项目中的properties文件夹下有个AssemblyInfo.cs

 

)]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration(
"")]
[assembly: AssemblyCompany(
"Microsoft")]
[assembly: AssemblyProduct(
"BugFix")]
[assembly: AssemblyCopyright(
"Copyright @ Microsoft 2004")]
[assembly: AssemblyTrademark(
"")]
[assembly: AssemblyCulture(
"")]

 

这些就是属性的基本格式了,即用方括号把属性括起来.assembly:标记定义了属性的作用域,其它代码声明了属性,就拿AssemblyTitle属性来说,它有一个构造函数,只有一个参数---字符串值.我们如果要访问这个值的话,可以通过Ildasm查看程序集,或通过"反射"编程访问该值.

说到"反射",也顺带提下吧,反射就是用编程的方式查看程序集,获得程序集的信息,这些信息包含所有对象的类型,用户添加到这些类型中的属性等.用到反射的话,我们要引入System.Reflection这个命名空间.

 

唠叨完属性的基础知识,就进入我们今天的正题--定制属性(就是创建自己的属性).

定制属性分为三个步骤

1.创建一个派生于System.Attribute的类

2.按照需要创建构造函数和公共属性

3.给类添加属性,以定义可以在什么地方使用定制属性

 

下面结合一个实例来讲

首先创建一个控制台应用程序,命名为BugFix

不要忘了引入两个重要的命名空间

using System;
using System.Reflection;

 

接着我们就开始创建自己的属性


   AttributeTargets.Property |
   AttributeTargets.Method 
|
   AttributeTargets.Constructor,
   AllowMultiple 
= true)]
public class BugFixAttribute : Attribute  //定制一个BugFixAttribute属性类
{
    
public BugFixAttribute(string bugNumber, string comments)
    {
        BugNumber 
= bugNumber;
        Comments 
= comments;
    }

    
public readonly string BugNumber;
    
public readonly string Comments;
    
public string Author = null;

    
public override string ToString() //重写ToString()方法
    {
        
if (null == Author)
            
return string.Format("BugFix {0} : {1}", BugNumber, Comments);
        
else
            
return string.Format("BugFix {0} by {1} : {2}", BugNumber, Author, Comments);
    }

    
public static void DisplayFixes(System.Type t)  //静态方法DisplayFix
    {
        
object[] fixes = t.GetCustomAttributes(typeof(BugFixAttribute), false);//反射t中的BugFix属性

        Console.WriteLine(
"Displaying fixes for {0}", t); 

        
foreach (BugFixAttribute bugFix in fixes)  
        {
            Console.WriteLine(
"  {0}", bugFix);
        }

        
foreach (MemberInfo member in t.GetMembers(BindingFlags.Instance |
                                                      BindingFlags.Public 
|
                                                      BindingFlags.NonPublic 
|
                                                      BindingFlags.Static))   
//迭代类上的所有成员,并用BindingFlags枚举限制返回成员列表
        {
            
object[] memberFixes = member.GetCustomAttributes(typeof(BugFixAttribute), false);

            
if (memberFixes.Length > 0)   //如果Bugfix属性数目大于0
            {
                Console.WriteLine(
"  {0}", member.Name);  //输出这些成员

                
foreach (BugFixAttribute memberFix in memberFixes)  
                {
                    Console.WriteLine(
"    {0}", memberFix);
                }
            }
        }
    }
}

我们先是创建了一个BugFixAttribute类,让它继承Attribute类,它的构造函数有两个参数,都是string类型的.为什么这样呢,暂时放一放,呆会下面会提到.然后我们重写了ToString方法,接着就是最重要的一块,用静态方法DisplayFixes()反射BugFix属性

ps:

AttributeUsage:用来定义属性用在什么地方.

AllowMultiple:定义用户是否能给元素添加一个或多个相同的属性

BindingFlags:一个枚举.这里是用来限制返回成员类型的

BugFix属性怎么用呢,可以按照如下方式

 

{
    [BugFix("90125""Removed call to base()", Author = "Morgan")]
    
public MyBuggyCode()
    {
    }

    [BugFix(
"2112""Returned a non null string")]
    [BugFix(
"38382""Returned OK")]
    
public string DoSomething()
    {
        
return "OK";
    }
}

 

在第一段代码中,我们讲到BugFixAttribute的构造函数用两个参数,bugNumber即指一个错误号,就是上面的101,90125

而comments就是注释错误的信息.即"Create some methods","Removed call to base"等

 

我们创建DisplayFixes这个静态方法就是为了获取MyBuggyCode这个类的属性

最后通过调用DisplayFixes方法将获取的属性值输出

 

 BugRiddenCode
{
    public static void Main()  //入口函数,调用了DisplayFixes这个静态方法
    {
        BugFixAttribute.DisplayFixes(
typeof(MyBuggyCode));
        Console.ReadKey();
    }
}

 

输出结果如下:

 

 MyBuggyCode
 BugFix 101:Create some methods
 DoSomething
   BugFix 
38382:Returned OK
   BugFix 
2112:Returned a non null string
 .ctor
   BugFix 
90125 by Morgan:Removed call to base() 

 

ps: .ctor是指的构造函数

通过BugFix这个小例子,相信大家对定制属性有所了解

 

后话:

高效的使用属性,可以做很多事情

可以定义程序集的信息,如版权信息啊

可以将代码块标记为过时,以修订程序集

创建自己的属性可以测试代码

我们还可以通过属性生成数据库表等等,虽然可能花费我们大量的时间去研究,但都是值得的,大家有好的例子,不要忘了发出来探讨一下

 

相关文章:

  • 2021-11-19
  • 2021-07-03
  • 2021-11-13
  • 2021-08-01
  • 2021-10-29
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-06-03
  • 2022-12-23
  • 2021-11-07
  • 2021-08-28
  • 2022-12-23
  • 2022-12-23
  • 2021-11-25
相关资源
相似解决方案