gpt4 book ai didi

c# - DynamicMethod 和类型检查

转载 作者:太空狗 更新时间:2023-10-29 17:58:20 26 4
gpt4 key购买 nike

有人可以解释或指出为什么在下面的示例中没有进行运行时类型检查吗?字符串属性可以设置为任何类型值...
在非常意想不到的地方坚持这一点,真的很惊讶

using System;
using System.Reflection;
using System.Reflection.Emit;

namespace Dynamics
{
internal class Program
{
private static void Main(string[] args)
{
var a = new A();
a.Name = "Name";
Console.WriteLine(a.Name.GetType().Name);

PropertyInfo pi = a.GetType().GetProperty("Name");

DynamicMethod method = new DynamicMethod(
"DynamicSetValue", // NAME
null, // return type
new Type[]
{
typeof(object), // 0, objSource
typeof(object), // 1, value
}, // parameter types
typeof(Program), // owner
true); // skip visibility

ILGenerator gen = method.GetILGenerator();
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldarg_1);
gen.Emit(OpCodes.Call, pi.GetSetMethod(true));
gen.Emit(OpCodes.Ret);

SetValue setMethod = (SetValue)method.CreateDelegate(typeof(SetValue));

int val = 123;
setMethod(a, val);
Console.WriteLine(a.Name.GetType().Name);

A anotherA = new A();
anotherA.Name = "Another A";
setMethod(a, anotherA);
Console.WriteLine(a.Name.GetType().Name);
}
}

public class A
{
public string Name { get; set; }
}

public delegate void SetValue(object obj, object val);
}

最佳答案

我做了一个小实验:在你的类中添加了一个方法:

    static void SetValue1(A a, object v)
{
a.Name = (string)v;
}

SetValue1(a, 123); 当然会抛出 InvalidCastException。然后,我使用 ildasm.exe 反汇编代码。 SetValue1 如下所示:

.method private hidebysig static void  SetValue1(class ConsoleApplication2.A a,
object v) cil managed
{
// Code size 15 (0xf)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.1
IL_0003: castclass [mscorlib]System.String // <--- replace this with nop
IL_0008: callvirt instance void ConsoleApplication2.A::set_Name(string)
IL_000d: nop
IL_000e: ret
} // end of method Program::SetValue1

好的,让我们用 nop 替换转换 castclass [mscorlib]System.String 并用 ilasm.exe 重新编译。

现在,对带有错误类型参数的 SetValue1 的调用通过并产生与您的动态方法相同的结果。所以在这种情况下,CLR 似乎没有进行类型检查。documentation说:

During just-in-time (JIT) compilation, an optional verification process examines the metadata and Microsoft intermediate language (MSIL) of a method to be JIT-compiled into native machine code to verify that they are type safe. This process is skipped if the code has permission to bypass verification.

在这种情况下,我们在本地机器上运行代码,因此 CLR 相信 IL 是有效的。

您可以通过在输出 .exe 文件上运行 peverify.exe 来手动验证程序集。它将返回错误:Program::SetValue1][offset 0x00000004][found ref 'System.Object'][expected ref 'System.String'] 堆栈上的意外类型。

有一篇很好的文章探讨了这个主题:http://www.pcreview.co.uk/forums/net-type-safety-and-net-configuration-tool-t1225543.html

关于c# - DynamicMethod 和类型检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17971700/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com