《隨筆九》——C#中的 “ typeof運算子 和 GetType() 函式”
● C#中任何物件都具有GetType()方法,x.GetType(),其中x為變數名。它的作用和typeof()相同,返回Type型別的當前物件的型別。
typeof(x)中的x,必須是具體的類名、型別名稱等,不可以是變數名稱;GetType()是基類System.Object的方法,因此只有建立一個例項之後才能夠被呼叫.
System.Type.GetType(),有兩個過載方法, typeof 不能過載。
比如有這樣一個變數i:
Int32 i = new Int32();
使用GetType(),i.GetType()返回值是Int32的型別,但是無法使用typeof(i),因為i是一個變數,
使用typeof(),則只能:typeof(Int32),返回的同樣是Int32的型別。
兩者區別:
1、typeof是運算子而不是方法
2、GetType()是基類System.Object的方法,因此只有建立一個例項之後才能夠被呼叫(初始化以後)
3、typeof的引數只能是內建型別 ,自定義型別,且不能是例項
4、GetType()和typeof都返回System.Type的引用.
5、typeof():得到一個Class的Type
6、 GetType():得到一個例項的Type
下面我們具體來看下相關類的介紹:
System.Type類
System.Type類定義了很多成員,可以用來檢查某個型別的元資料,它們返回的型別大多位於System.Reflection名稱空間中。舉例來說,Type.GetMethods()返回一個MethodInfo型別的陣列,Type.GetFields返回一個FieldInfo型別的陣列等。System.Type提供的完整的成員組是很容易擴充套件的。
使用System.Object.GetType()得到Type引用
可以用多種方法得到一個Type類的例項。但是,由於Type是一個抽象類,所以不能直接使用new關鍵字建立一個Type物件。對此我們的首選是:使用System.Object定義的GetType()方法,它返回一個表示當前物件元資料的Type類的例項:
//使用一個SportsCar例項得到型別資訊
SportsCar sc = new SportsCar();
Type t = sc.GetType();
顯而易見,要想使用這個方法,必須得到型別的編譯時資訊(這裡是SportsCar類),並且當前在記憶體中型別例項。
使用typeof()得到Type引用
另一個取型別資訊的方法是使用C# typeof操作符:
//使用typeof得到型別
Type t = typeof(SportsCar);
類似System.Object.GetType(),使用typeof操作符,我們不需要建立一個例項來提取型別資訊。但是,仍然需要知道型別的編譯時資訊,因為typeof需要的是型別的強型別名稱,而不是文字表示。
使用System.Type.GetType()得到Type引用
為了以更靈活的方式得到型別資訊,我們可以呼叫System.Type類的靜態成員GetType(),然後指定型別的完全限定名。採用這種方法,我們不需要得到正從中提取元資料的型別的編譯時資訊,
Type.GetType()方法被過載一:
允許我們指定兩個布林型別的引數,一個用來控制當型別找不到時是否丟擲異常,另一個用來指示是否區分字串大小寫。
例如:
//使用靜態的Type.GetType()方法獲取型別資訊(如果SportsCar沒有找到,則忽略不丟擲異常資訊)
Type t = Type.GetType("CarLibrary.SportsCar",false,true);
Type.GetType()方法被過載二:
在上面的例子中,注意傳入GetType()的字串沒有包含型別所在的程式集資訊。在這種情況下,該型別便被認為是定義在當前執行的程式集中。但是,當希望得到一個外部私有程式集的型別元資料時,字串引數必須使用型別完全限定名,加上型別所在的程式集的名字(每一個都用逗號隔開):
//得到外部程式集中型別的型別資訊
Type t= Type.GetType("CarLibrary.SportsCar,CarLibrary");
#region Using directives
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using static System.Console;
using static System.Convert;
#endregion
using System.Reflection; //使用反射名稱空間來全面利用檢測型別資訊的功能
namespace Ch05Ex03
{
class SomeClass
{
public int Field1;
public int Field2;
public
void Method1()
{ }
public
int Method2()
{
return 1;
}
}
class Program
{
static void Main(string[] args)
{
Type t = typeof(SomeClass);
FieldInfo[] fi = t.GetFields();
MethodInfo[] mi = t.GetMethods();
foreach(FieldInfo f in fi)
{
WriteLine("Filed: {0}",f.Name);
}
WriteLine();
foreach (MethodInfo m in mi)
{
WriteLine("Method: {0}", m.Name);
}
ReadKey();
}
}
}
輸出結果為:
Filed: Field1
Filed: Field2
Method: Method1
Method: Method2
Method: ToString
Method: Equals
Method: GetHashCode
Method: GetType