1. 程式人生 > >《隨筆九》——C#中的 “ typeof運算子 和 GetType() 函式”

《隨筆九》——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