iluxa1810 Asked:2020-11-16 17:21:58 +0000 UTC2020-11-16 17:21:58 +0000 UTC 2020-11-16 17:21:58 +0000 UTC 在 IL 中哪些是 .NET 高级语言无法做到的? 772 一般来说,之所以提出这个问题,是因为另一个问题的答案。 它认为IL可以在没有封装的情况下访问代码中另一个类的私有字段,自然而不需要使用昂贵的反射。 (是这样吗?) 事实证明,我可以将IL编译后获得的 -code并添加一些高级语言无法实现的C#奇异行为(其中不禁止),编译并将此程序集连接到项目并透明使用IL它就一些C#? 实际上,这些库的用户允许多少所有内容IL以及可能产生的副作用的问题是令人感兴趣的。 .net 3 个回答 Voted Best Answer Pavel Mayorov 2020-11-19T15:33:01Z2020-11-19T15:33:01Z IL 的功能比 C# 的功能要广泛一些,例如,您可以通过引用解包对象: ldarg_0 unbox [mscorlib]System.Int32 ldc.i4 42 stobj [mscorlib]System.Int32 ret 这就是它的结果: object obj = -1; Foo(obj); Console.WriteLine(obj); // 42 但是,C# 和 IL 的大多数限制是普遍的:C# 语言,特别是在最近的版本中,允许运行时允许的很多内容。是的,您不能只访问 IL 中的私有字段。 实际上,在您给出的示例中,访问私有字段成为可能,不仅因为它是 IL,还因为使用了动态方法。 如果创建它们的代码具有足够的权限,则动态方法可以绕过可见性检查(并且已通过构造函数参数为该方法启用了检查绕过) Qwertiy 2020-11-16T23:35:55Z2020-11-16T23:35:55Z 在 il-code中,您可以将函数标记为可导出,可以从本机(非本机)代码调用。显然,MS 本身根本没有宣传这种可能性。他们肯定没有将此功能添加到 C# 和 VB.NET 编译器中,他们不知道这些优点。 nick_n_a 2020-11-16T23:16:19Z2020-11-16T23:16:19Z 使用 IL,您可以按照您想要的任何顺序执行 CLR 命令https://en.wikipedia.org/wiki/List_of_CIL_instructions。你甚至可以违反安全概念,等等不被禁止。反射本身允许访问类的私有成员和其他成员。而IL是一种命令语言。您可以创建优化良好的 IL 代码和破坏应用程序的代码。 但重要的是 IL 代码不能“单独”存在,它被打包为程序集。例如,此属性用于生成实体。查看代码 foreach (PropertyInfo prop in obj.Props) do_something 在 IL 上,您可以通过这样的循环(有条件地)实现它https://subscribe.ru/archive/comp.soft.prog.csharplessons/200703/21001224.html/ ldarg.1 getprop a do_something ldarg.1 getprop b do_something 但是您需要了解这个 il (不是由您生成,而是由您的自动机生成) foreach (PropertyInfo prop in obj.Props) { il.Emit(OpCodes.ldarg1); //.... } 您需要创建一个程序集,如果使用动态程序集,则会创建一个临时程序集(带有 dll 的临时文件)。 关于速度,IL编译需要时间(如果使用动态生成IL代码),如果使用该机制1次,将没有加速。如果您有一百万次调用属性(这在 DBMS 中通常是这种情况),那么最好创建一个程序集。因为对于通过通常的反射(foreach、Properties、SetValue)进行访问,使用的 IL 命令比仅通过 IL(三个命令 ldarg、ldarg、setprop 加减号)多 10-20 倍。有些会自动执行此操作。 通常,IL 允许您制作自修改(有条件地)代码,或编译代码而不求助于“csc.exe”。 如果目标是访问私有属性,那么通常只需通过反射即可访问它。
IL 的功能比 C# 的功能要广泛一些,例如,您可以通过引用解包对象:
这就是它的结果:
但是,C# 和 IL 的大多数限制是普遍的:C# 语言,特别是在最近的版本中,允许运行时允许的很多内容。是的,您不能只访问 IL 中的私有字段。
实际上,在您给出的示例中,访问私有字段成为可能,不仅因为它是 IL,还因为使用了动态方法。
如果创建它们的代码具有足够的权限,则动态方法可以绕过可见性检查(并且已通过构造函数参数为该方法启用了检查绕过)
在 il-code中,您可以将函数标记为可导出,可以从本机(非本机)代码调用。显然,MS 本身根本没有宣传这种可能性。他们肯定没有将此功能添加到 C# 和 VB.NET 编译器中,他们不知道这些优点。
使用 IL,您可以按照您想要的任何顺序执行 CLR 命令https://en.wikipedia.org/wiki/List_of_CIL_instructions。你甚至可以违反安全概念,等等不被禁止。反射本身允许访问类的私有成员和其他成员。而IL是一种命令语言。您可以创建优化良好的 IL 代码和破坏应用程序的代码。
但重要的是 IL 代码不能“单独”存在,它被打包为程序集。例如,此属性用于生成实体。查看代码
在 IL 上,您可以通过这样的循环(有条件地)实现它https://subscribe.ru/archive/comp.soft.prog.csharplessons/200703/21001224.html/
但是您需要了解这个 il (不是由您生成,而是由您的自动机生成)
您需要创建一个程序集,如果使用动态程序集,则会创建一个临时程序集(带有 dll 的临时文件)。
关于速度,IL编译需要时间(如果使用动态生成IL代码),如果使用该机制1次,将没有加速。如果您有一百万次调用属性(这在 DBMS 中通常是这种情况),那么最好创建一个程序集。因为对于通过通常的反射(foreach、Properties、SetValue)进行访问,使用的 IL 命令比仅通过 IL(三个命令 ldarg、ldarg、setprop 加减号)多 10-20 倍。有些会自动执行此操作。
通常,IL 允许您制作自修改(有条件地)代码,或编译代码而不求助于“csc.exe”。
如果目标是访问私有属性,那么通常只需通过反射即可访问它。