C# 中“自定义属性” 功能和 反射的使用 例子

这里的“属性”指的是 “Attribute ”,另外一个名字是“ metadata” (元数据?)。

就是嵌入在对象中的运行时信息了,可以在你的程序中在运行时检查到,便于控制你的程序如何处理数据。结合反射(Reflection)来使用可以实现很有意思的应用。 这个用法在自定义框架里面经常会看到的,就是声明类或者方法的时候在前面用 [xxxxx] 这样的中括号来定义属性 ,下面代码里面有用法了。更详细 的解释,可以去看一下(http://hi.baidu.com/widebright/blog/item/1df9d762ab9deadfe7113a81.html),这里也有一个应用的例子(http://hi.baidu.com/widebright/blog/item/04759058143725db9c82041b.html)。


下面的代码定义了一个名字为widebright的自定义的属性,然后还有测试使用的例子,用到了“反射”了,其实我也接触不多“反射”这个东西,就是个提供运行时获取类结构等的支持的东西了,还可以用来动态加载库等,好像。

//这里利用AttributeUsage 来设置我们的自定义属性的应用范围,这里定义的可以用于类,结构和方法的声明
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method,
       AllowMultiple 
= true)] // multiuse attribute
    class widebright : Attribute //从Attribute 继承,写一个自定义属性
    {
        
private string strname;
        
public widebright(string name)
        {
            strname 
= name;
        }

        
//添加一个允许外部访问的属性
        public string Name
        {
            
get { return strname; }
            
set { strname = Name; }
        }
    }
//写一个测试类
    [widebright("widebright")]
    
class widebrightTestClass
    {
        
private string name = "hahaa";
        [widebright(
"test1")]
        
public void TestMethod()
        {
            System.Console.WriteLine(
"哈哈,第一个测试通过");
        }
        [widebright(
"test2")]
        
public void TestMethod2(string parm)
        {
            System.Console.WriteLine(
"哈哈,第二个测试通过,传过来的参数是:{0}", parm);
        }

        
public void TestMethod3()
        {
            System.Console.WriteLine(
"哈哈,第三个测试,name的值为{0}"this.name);
        }
    }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ConsoleApplication1
{
    
class Program
    {
        
static void Main(string[] args)
        {
            widebrightTestClass testClass 
= new widebrightTestClass();
            
//在程序运行时,获取自己添加进去的“自定义属性”
            Type type = testClass.GetType();
            testClass.TestMethod3();

            
//利用反射 运行时修改对象的私有属性
            BindingFlags flags = (BindingFlags.NonPublic | BindingFlags.Instance);
            type.GetField(
"name", flags).SetValue(testClass, "widebright");

            
//再次调用方法,应该可以看到name私有属性确实被修改成widebright了
            testClass.TestMethod3();

            
foreach (Attribute attr in type.GetCustomAttributes(false))
            {
                
if (attr.GetType() == typeof(widebright))
                {
                    System.Console.WriteLine(
"testClass 对象具有 widebrihgt这个自定义属性");
                }

            }

            
//测试 widebright”自定义属性“时候存在,获取type的所有方法
            foreach (MethodInfo mInfo in type.GetMethods())
            {

                
foreach (Attribute attr in
                   Attribute.GetCustomAttributes(mInfo))
                {
                    
// Check for the AnimalType attribute.
                    if (attr.GetType() == typeof(widebright))
                    {
                        Console.WriteLine(
                            
" {0}方法有一个 名字为{1} 的\"widebright\" 属性.",
                            mInfo.Name, ((widebright)attr).Name);
                        
if (((widebright)attr).Name == "test2")
                        {
                            
//动态调用testClass对象的方法
                            mInfo.Invoke(testClass, new string[] { ((widebright)attr).Name });
                        }
                        
else
                        {
                            
//第一个方法没有参数,所以传个null给他
                            mInfo.Invoke(testClass, null);
                        }

                    }
                    
else
                    {
                        Console.WriteLine(
                          
" {0}方法不具有\"widebright\" 属性.",
                          mInfo.Name);

                    }

                }


            }
        }
    }
}

测试程序代码下载,但代码获取类的属性有点变动。请看源码

原文地址:https://www.cnblogs.com/stalwart/p/2031362.html