TypeInfo和Type的區別與選擇
概念
TypeInfo出現於.net framework 4.5之後,這次調整用於區分兩個概念:“reference”和“definition”。
reference is a shallow representation of something
definition is a rich representation of something
例如System.Reflection.Assembly就代表了一個“definition” ,而System.Reflection.AssemblyName就代表了一個“reference”
在未區分這兩種概念之前,System.Type
public MyClass:BaseClass{
}
//獲得MyClass的型別物件
Type t=MyClass.GetType();
在.net framework 4中,獲得型別物件時,同時獲得了基類(BaseClass)的型別物件,同時包括基類物件的“reference
在.net framework 4.5中,如下程式碼:
Type baseType = MyClass.GetType().GetTypeInfo().BaseType;
在獲得型別物件時,只獲得了基類的"reference"
使用
在明確概念後,具體什麼屬性和方法屬於"definition",什麼屬性和方法屬於"reference",我並沒有很清晰,以下只是做一個粗糙的說明。
最簡單的理解就是:System.Reflection.TypeInfo中的屬性和方法即是"definition",而去除掉System.Type中與TypeInfo重合的部分,剩下的即是"reference
簡單比較一下可以發現:
public class Type:MemberInfo
{
public bool Is*();
public MemberInfo[] GetMembers();
public virtual MemberInfo[] GetMember(string name, BindingFlags bindingAttr);
}
public class TypeInfo:Type
{
public IEnumerable<MemberInfo> DeclaredMembers{get;}
}
下面針對以上程式碼,從以下幾個角度進行說明:
型別繼承:TypeInfo繼承自Type,但實際上
右圖才是真正實現了概念分離的程式碼結構,現在的設計,只是為了相容之前的版本
返回內容:
Get*()返回的是當前型別定義的MemberInfo以及其基類的public型別的MemberInfo
Declear*屬性返回的是當前型別定義的Member Info
返回資料型別:
Get*()返回的是Array型別
Declear*屬性返回的是IEnumerable<>型別,此型別具有延遲載入的功能,因為如果要返回Array型別,必須將Array填滿後返回,而IList和IEnumerable只是實現了一個狀態機,這裡沒有使用IList的原因是,IEnumerable更加簡潔
返回資料過濾
Get*()方法含有BindingFlags引數,用來選擇返回的MemberInfo是Public還是Static...
Declear*()的方法並不含有BindingFlags引數,因此需要使用LINQ進行查詢過濾