簡體   English   中英

Reflection.Emit如何分配不兼容的類型?

[英]How can Reflection.Emit assign incompatible types?

我有兩個簡單的課程。

public class A { }
public class B { }

我構建並實例化C類,如下所示。

var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("Some.Namespace"), AssemblyBuilderAccess.Run);
var moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyBuilder.GetName().Name);

// public class C
var typeBuilder = moduleBuilder.DefineType("C", TypeAttributes.Public | TypeAttributes.Class, typeof(object));

// public A A;
var aField = typeBuilder.DefineField("A", typeof(A), FieldAttributes.Public);

// public C() { this.A = new B(); } !!!!
var ctorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, Type.EmptyTypes);
var ctorIL = ctorBuilder.GetILGenerator();
ctorIL.Emit(OpCodes.Ldarg_0);
ctorIL.Emit(OpCodes.Newobj, typeof(B).GetConstructor(Type.EmptyTypes));
ctorIL.Emit(OpCodes.Stfld, aField);
ctorIL.Emit(OpCodes.Ret);

// return new C();
var type = typeBuilder.CreateType();
return Activator.CreateInstance(type);

問題是我可以成功實例化C類。 當我檢查CA的類型和價值時,對我來說這是非常令人驚訝的。

var c = CreateC();

var field = c.GetType().GetField("A");
var fieldValue = c.GetType().GetField("A").GetValue(c);

Console.WriteLine(typeof(A) == field.FieldType);      // True
Console.WriteLine(typeof(A) == fieldValue.GetType()); // False
Console.WriteLine(typeof(B) == field.FieldType);      // False   
Console.WriteLine(typeof(B) == fieldValue.GetType()); // True

簡而言之,我有以下課程正在運作!

public class A { }
public class B { }

public class C 
{
    public A A;
    public C() 
    {
        this.A = new B();
    }
}

我的問題是:

  1. 這怎么可能?
  2. CLR在哪個級別檢查類型?

如果您的代碼在完全信任下運行,則CLR不會檢查IL是否“可驗證”。 這意味着代碼可以執行各種瘋狂的操作,並且您有責任確保您發出的代碼是類型安全的。

但是,如果您的代碼在部分信任下運行,那么Activator.CreateInstance(type)將拋出System.Security.VerificationException (“Operation可能會破壞運行時的穩定性”)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM