C# 反射.Emit如何分配不兼容的类型?

C# 反射.Emit如何分配不兼容的类型?,c#,reflection,reflection.emit,C#,Reflection,Reflection.emit,我有两个简单的课程 public class A { } public class B { } 我构建并实例化类C,如下所示 var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("Some.Namespace"), AssemblyBuilderAccess.Run); var moduleBuilder = assemblyBuilder.DefineDynamicModul

我有两个简单的课程

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
。 当我检查
C.A
的类型和值时,我感到非常惊讶

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();
    }
}
我的问题是:

  • 这怎么可能呢
  • CLR在哪个级别检查类型

  • 如果您的代码在完全信任的情况下运行,那么CLR不会费心检查IL是否“可验证”。这意味着代码可以做各种疯狂的事情,你有责任确保你发出的代码是类型安全的


    但是,如果您的代码在部分信任下运行,那么
    Activator.CreateInstance(type)
    将抛出(“操作可能会破坏运行时”)。

    实际上一切都正常工作。字段类型、声明类型和字段值类型是完全不同的。这是您的测试显示的。那么,构造函数如何在没有任何异常的情况下执行?我不明白您为什么期望出现异常。在普通代码中是否有异常?还有什么例外?