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手记

优质内容筛选与推荐>>
1、多线程start()与run()区别
2、Microsoft Asp.Net Ajax框架入门(10) ScriptManager, UpdatePanel, Timer
3、jsp文件下载
4、html5-颜色的表示
5、Kali安装vmtools提示缺少内核头文件的解决办法


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号