程序集加載與反射(一):理論篇


目錄

  • 程序集加載
  • 獲取類型信息
  • 構造類型實例
  • 通過反射發現成員
  • 調用成員

 

一、程序集加載

Load方法:CLR通過調用System.Rreflection.Assemblly類的靜態方法來顯示加載程序集。

public static Assembly Load(AssemblyName assemblyRef);
public static Assembly Load(string assemblyString);


LoadFrom方法:同樣我們可以使用 遠程加載程序集。此方法首先打開程序集,並通過 public static AssemblyName GetAssemblyName(string assemblyFile);方法提取到程序集名稱,然后再會使用Load方法加載程序集。

public static Assembly LoadFrom(string path);

ReflectionOnlyLoad方法:加載程序集,只是獲取程序集的相關信息。但CLR禁止此程序集中的代碼執行。

public static Assembly ReflectionOnlyLoad(string assemblyString);

同樣也有ReflectionOnlyLoadFrom

public static Assembly ReflectionOnlyLoadFrom(string path);

 

二、獲取類型信息

1、System.Type.GetType方法

public static Type GetType(string typeName);

字符串必須執行的是全名,對於基元類型不能識別,識別CLR類型。

2、System.Type.ReflectionOnlyGetType

public static Type ReflectionOnlyGetType(string typeName, bool throwIfNotFound, bool ignoreCase);

只是顯示反射上下文內容,不能夠執行代碼。

3、操作符typeof(),可以對類型進行晚期綁定並與早期綁定類型進行比對。

static Encryption(object o)
        {
             //早期綁定:o.GetTye()  
             //晚期綁定typeof
            if (o.GetType() == typeof(Encryption))
            {
            }
        }   

 

三、構造類型實例

1、System.Activator.CreateInstance

public static object CreateInstance(Type type);
public static ObjectHandle CreateInstance(string assemblyName, string typeName);

 上面的方法返回值有的是ObjectHandle類型,此類型允許將一個AppDomian中的對象傳送到另一個AppDomian而且不需要具體化哪個對象。如果需要具體化具體的類型就可以調用 Unwrap()方法。

 2、System.Activator.CreateComInstanceFrom

public static ObjectHandle CreateComInstanceFrom(string assemblyName, string typeName);

程序集和類型都是字符串直接指定,不過,程序集需要使用LoadFrom方法來加載得到程序集,並且提取名稱作為參數傳遞。當然對於返回值我們也需要調用Unwrap()進行具體化。

System.Reflection.Assembly assy= System.Reflection.Assembly.LoadFrom("");

System.Activator.CreateComInstanceFrom(assy.FullName, "Encryption");

 

四、通過反射發現成員

 層次結構

 因為Reflection.MemberInfo是成員結構層次的根,所以需要了解一下MemberInfo的成員組成:

 1、執行以下代碼,區分一下DeclaringType和ReflectedType:

DeclaringType:聲明方法的類;ReflectedType:當前的反射類

 public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            System.Reflection.MemberInfo[] mi = typeof(MyType).GetMembers();            

            foreach (var m in mi)
            {
               var dt=  m.DeclaringType;

               var rt = m.ReflectedType;
            }
        }
    }
    public sealed class MyType
    {

        public override string ToString()
        {
            return null;
        }
    }

ToSting()方法,因為聲明它的類和當前所在的反射類是同一個即MyType。

Equal()方法,因為聲明它的類是Object,但是當前反射類是MyType。

以上就是DeclaringType和ReflectedType的區別。

 

2、BindingFlags:篩選返回的成員種類

我們可以調用Type的 GetMethod、GetProperty、GetNestedType各種Get。我們可以組合BindingFlags,來篩選我們需要的東西。

 

五、調用成員的類型

我們可以找出我們需要的東東,然后我們可以進行調用。調用屬性、方法、構造函數等等。

調用FieldInfo,可以獲取或者設置字段的值;

調用ConstructorInfo,可以向構造傳遞實參,從而構造類型的一個實例;

調用MethodInfo,可以通過傳遞實參來調用方法,並返回它的返回值;

調用PropertyInfo,可以調用屬性的get和set訪問其方法。

 1、調用方法

public object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, CultureInfo culture);

調用此方法可以在成員類型里搜索一個匹配的類型成員,如果沒找到,拋出異常。如果找到,就會調用此成員。我們可以歸納以上行為為兩個階段:綁定和調用。

我們調用一個綁定器方法時,首先我們傳遞 目標成員 name、方法的所有參數類型 args 、指定的 BindingFlags invokeAttr 。

參數 name :目標成員。名字

參數 invokeAttr :這些位標識的組合可以幫助我們更好的定位我們的成員 IgnoreCase = 1, DeclaredOnly = 2,Instance = 4,Static = 8,Public = 16等

參數 binder :它的類型從System.Relflection.Binder 抽象類型派生的,從Binder派生的類型,封裝了InverMember方法確定綁定類型的規則。編譯器為我們定義了System.DefaultBinder 的實際類型可以為我們使用。可以幫助我們自動的類型轉換。

參數 target : 目標成員所在類的實例的一個引用。靜態類 =null。

參數 args: 傳遞的參數。

參數 culture: 如果有自己的綁定器可以使用此參數,如果前面參數使用了System.DefaultBinder,culture參數就可以省略了。

2、一次綁定,多次調用

我們利用Type的InvokeMember方法可以,訪問任何成員。但是如果多次調用,我們就需要多次進行綁定並調用,比較損耗性能。我們可以使用:

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM