反射和屬性

?反射的概念

?反射遍歷成員

?用射調用類型成員

?屬性概念(Attribute

?屬性的實例

?自定議屬性

?三個屬性

二次編輯一次運行

 

一次編譯後

 

反射

反射是編程的讀取與類型相關聯的元數據的行爲。通讀取元數據,可以瞭解它是什麼類型以及類型的成員。比如類中的屬性,方法,事件等。

所屬命名空間System.Reflection

反射-反射成員名稱

class Demo_Class

{

public Demo_Class(int i)

{

Console.WriteLine("構造函數:" + i);

}

public void Method(string s)

{

Console.WriteLine("A類參數爲:" + s);

}

public int i;

public string S

{

get; set;

}

}

調用

static void Main(string[] args)

{

Type type = typeof(Demo_Class);

MemberInfo[] MI = type.GetMembers(BindingFlags.NonPublic | BindingFlags.Public |BindingFlags .Instance );

foreach (MemberInfo mi in MI)

{

Console.WriteLine("名稱:{0},類型:{1}",mi.Name,mi.MemberType .ToString ());

}

}

運行結果

 

反射-用反射調用無參構造類型成員

class Demo_Class

{

public void Method(string s)

{

Console.WriteLine("A類參數爲:" + s);

}

}

class Program

{

static void Main(string[] args)

{

BindingFlags bf = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;

Type t = typeof(Demo_Class);

ConstructorInfo Cons = t.GetConstructor(new Type[0]); //構造函數無參,所以構造函數無類型參數

object Obj = Cons.Invoke(null);//傳入的構造參數爲空,得到對象

object[] MethodPar = new object[] { “a” }; //方法的參數

MethodInfo mi = t.GetMethod(“Method”, bf);//得到方法

Console.WriteLine(mi.Invoke(Obj, MethodPar));

}

}

反射-用反射調用有參構造類型成員

class Demo_Class

{

public void Method(string s)

{

Console.WriteLine("A類參數爲:" + s);

}

}

class Program

{

static void Main(string[] args)

{

BindingFlags bf = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;

Type t = typeof(Demo_Class);

ConstructorInfo Cons = t.GetConstructor(new Type[]{typeof(int)}); //構造函數有參,類型爲int

object Obj = Cons.Invoke(net object[]{123});//傳入的構造參數, 得到對象

object[] MethodPar = new object[] { “a” }; //方法的參數

MethodInfo mi = t.GetMethod(“Method”, bf);//得到方法

Console.WriteLine(mi.Invoke(Obj, MethodPar));

}

}

屬性-Attribute

Attributeproperty(類的成員)

屬性提供功能強大的方法以將聲明信息與 C# 代碼(類型、方法、屬性等)相關聯。

屬性與程序實體關聯後,即可在運行時使用名爲反射的技術查詢屬性。

屬性以兩種形式出現:

1.一種是在公共語言運行庫 (CLR) 中定義的屬性。

2.另一種是可以創建的用於向代碼中添加附加信息的自定義屬性。此信息可在以後以編程方式檢索。

屬性具有以下特點:

1.屬性可向程序中添加元數據。元數據是嵌入程序中的信息,如編譯器指令或數據描述。

2.程序可以使用反射檢查自己的元數據。

3.通常使用屬性與 COM 交互。

一個例子:

[System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "MessageBoxW")]

public static extern int MessageBoxW([System.Runtime.InteropServices.InAttribute()] System.IntPtr hWnd, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)] string lpText, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)] string lpCaption, uint uType);

static void Main(string[] args)

{

Console .WriteLine ( MessageBoxW(IntPtr .Zero , "確定嗎?", "提示",1));

}

自定義屬性

通過定義一個屬性類,可以創建您自己的自定義屬性。該屬性類直接或間接地從System. Attribute 派生,有助於方便快捷地在元數據中標識屬性定義。假設您要用編寫類或結構的程序員的名字標記類和結構。

[System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Struct,AllowMultiple=true ,Inherited =true ) ] //Author屬性只能用於類和結構,AllowMultiple是否允許多次用屬性,Inherited是這個屬性是滯延續到子類。

public class Author : System.Attribute

{

private string name;

public double version;

public Author(string name)

{

this.name = name; version = 1.0;

}

}

[Author(“張三”, version =2.0)]//張三是Author的構造函數的參數,version是字段

class SampleClass

{ }

三個特別的屬性

1.AttributeUsage屬性(上面的例子已經演示)

2.Conditional屬性

3.Obsolete屬性

三個特別的屬性- Conditional

條件方法必須是類或結構聲明中的方法,而且必須具有 void 返回類型。

#define TRACE_ON //這行標識代碼決定着紅色代碼的執行與否。

using System;

using System.Diagnostics;

namespace R_A_Demo

{

public class Trace

{

[Conditional("TRACE_ON")]

public static void Msg(string msg)

{

Console.WriteLine(msg);

}

}

public class ProgramClass

{

static void Main()

{

Trace.Msg(“調試信息”);

Console.WriteLine(“代碼正體");

}

}

}

另一種用法

#define TRACE_ON

using System;

using System.Diagnostics;

namespace R_A_Demo

{

public class Trace

{

#if TRACE_ON

public static void Msg(string msg)

{

Console.WriteLine(msg);

}

#endif

}

public class ProgramClass

{

static void Main()

{

Trace.Msg("Now in Main...");

Console.WriteLine("Done.");

}

}

}

三個特別的屬性- Obsolete

[System.Obsolete("use class B")] //類會被在實例化時警告

class A

{

public void Method() { }

}

class B

{

[System.Obsolete("use NewMethod", false )] //方法調用時提示信息

public void OldMethod() { }

[System.Obsolete("use NewMethod", true)] //不可編譯

public void NewMethod() { }

}

一句話總結:

反射:利用一次編譯後的結果,反得到類型和類型成員。

屬性(Attribute):額外給其他類型添加信息的類型。

 

 

發佈了18 篇原創文章 · 獲贊 2 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章