zoukankan      html  css  js  c++  java
  • C# 中“自定义属性” 功能和 反射的使用 例子

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

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

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

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;

    using System.Reflection;

    namespace WindowsFormsApplication1
    {
        //这里利用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);
            }
        }

        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }

            private void Form1_Load(object sender, EventArgs e)
            {
                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 );
                        }
                   }

            }
          }

        }

    运行程序后将打印:

    哈哈,第三个测试,name的值为hahaa
    哈哈,第三个测试,name的值为widebright
    testClass 对象具有 widebrihgt这个自定义属性
    TestMethod方法有一个 名字为test1 的"widebright" 属性.
    哈哈,第一个测试通过
    TestMethod2方法有一个 名字为test2 的"widebright" 属性.
    哈哈,第二个测试通过,传过来的参数是:test2

    很有意思用法,呵呵, widebright手记

    联盟快卖 商人,生意人,待创业人士在此可以共赢互利 期待你的加入 群号:140809277
  • 相关阅读:
    Tasklet机制
    linux 内核与用户空间通信之netlink使用方法
    inline总结与思考
    PF_NETLINK应用实例NETLINK_KOBJECT_UEVENT具体实现--udev实现原理
    2410下DMA驱动源码分析
    [转]数据库建立索引的一般依据
    [转]性能调优的步骤
    [原] JT SQL Server 性能调优札记之二
    [转]SQL Server 2000执行计划成本(5/5)
    [转]SQL Server 2000执行计划成本(3/5)
  • 原文地址:https://www.cnblogs.com/yexinw/p/2090415.html
Copyright © 2011-2022 走看看