我使用过Microsoft ILGenerator及其Emit成员.我想知道在哪里可以找到由它生成的输出il文件.
我真的想在运行时生成一个新类型.基本上,我想创建看起来像这样的类型:
public class MySpecial123
{
public Func<int, DateTime, int> salesVectorCalc; // field
public int CallSalesVectorCalculation(int i, DateTime d)
(
return salesVectorCalc(i, d);
)
}
Run Code Online (Sandbox Code Playgroud)
一些类型将根据用户/数据库输入而有所不同,因此我无法以任何其他方式完成它,然后在运行时创建类型.还有更复杂的问题,但我想让我的问题变得简单,所以我只是在这里提出基本问题.我需要做更多代,就像你在这里看到的那样.
我认为使用它会很酷Reflection.Emit,但后来我意识到生成代码并在内存中编译所有内容可能更容易.有谁知道哪个更好?我真的想看一个如何做其中任何一个的例子.
由于前一个问题不够清楚,这就是我需要帮助的精确方法.
如何使用OpCodes.Call生成此代码:
return Enumerable.ToList<Potato>(Eumerable.Cast<Potato>(_proxyPotatoes));
Run Code Online (Sandbox Code Playgroud)
这是我正在尝试做的一个例子:
public class Potato
{
}
public class ProxyPotato : Potato
{
}
public class Stew
{
private ICollection<ProxyPotato> _proxyPotatoes;
//This is the code I would like to generate (specialy the cast part)
public ICollection<Potato> Potatoes { get { return _proxyPotatoes.Cast<Potato>().ToList(); } }
}
Run Code Online (Sandbox Code Playgroud)
编辑1
在@zmbq的建议之后,我需要生成两行IL:
call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0> [System.Core]System.Linq.Enumerable::Cast<class Maxime.Potato>(class [mscorlib]System.Collections.IEnumerable)
call class [mscorlib]System.Collections.Generic.List`1<!!0> [System.Core]System.Linq.Enumerable::ToList<class Maxime.Potato>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>)
Run Code Online (Sandbox Code Playgroud) 我一直在寻找一种方法,以确保在所有情况下(例如在类构造函数末尾的异常)都清除类的成员变量。
因为它们是成员变量,所以“尝试,捕获”和“使用”模式没有用。我注意到.NET C ++(C ++ / clr:safe)提供了对智能指针(称为msclr :: auto_handle)的仿真,例如auto_ptr或shared_ptr。这非常有用,因为我可以非常干净地确定性地破坏有限资源,例如线程或套接字。
我一直在分析用C ++ / clr生成的IL,并注意到它实际上所做的就是在修改封装数据的每个函数中都通过try / faults向IL垃圾邮件。
我已经为有兴趣的人列出了IL清单。(try / fault不是我添加的,而是C ++ / clr编译器添加的)
MyClass()
{
myDisposable.reset(gcnew MyDisposable());
throw gcnew Exception("Hello World");
// myDisposable needs to clean up now
// because it is very large or locks a limited resource.
// Luckily with RAII.. it does!
}
Run Code Online (Sandbox Code Playgroud)
...变成...
.try
{
IL_0006: ldarg.0
IL_0007: ldloc.0
IL_0008: stfld class msclr.'auto_handle<MyDisposable>' modreq([mscorlib]System.Runtime.CompilerServices.IsByValue) MyClass::myDisposable
IL_000d: ldarg.0
IL_000e: call instance void [mscorlib]System.Object::.ctor()
IL_0013: ldarg.0
IL_0014: ldfld class msclr.'auto_handle<MyDisposable>' …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用Mono.Cecil将代码注入程序集.到目前为止,一切都很好,但现在我正在尝试实现IL的这一点:
call bool [mscorlib]System.String::op_Equality(string, string)
Run Code Online (Sandbox Code Playgroud)
我怎么在塞西尔这样做?我知道它就像是
var il=mymethod.Body.GetIlProcessor();
...
il.Emit(Opcodes.Call, ????);
Run Code Online (Sandbox Code Playgroud)
我不知道要发送什么样的参数或如何获取对该静态函数的引用.
我该怎么做呢?
从IL 的角度来看,局部Dim变量和局部 静态变量之间的主要区别(性能方面)是什么?
我一直认为Dim每次都会分配存储空间,而Static只会分配一次存储空间,因此速度更快。但正如您在下面看到的,情况并非如此。

Public Class Form1
Public Sub New()
Me.InitializeComponent()
Dim b As New Button() With {.Text = "Run", .Height = 30, .Location = New Point(10, 10)}
AddHandler b.Click, AddressOf Me.Run
Me.Controls.Add(b)
End Sub
Private Sub Run(sender As Object, e As EventArgs)
Dim count As Integer = 10000
Dim watch As New Stopwatch()
Dim list As New Test(Of Control)(count)
Dim last As Control = list.Items(count - …Run Code Online (Sandbox Code Playgroud) 所以我是C#的中级程序员,最近我迷上了文件大小并创建了最小的文件。为此,我意识到将MSIL用于更简单的程序可以大量减少大小。
所以我尝试转换以下内容
现在,做完这些之后,我想...为什么当我可以简单地使用反射并不必使用磁盘就可以运行它们时编写文件?
那就是问题所在,我找不到解决方案。
此代码有什么问题?
.assembly a{}
.subsystem 0x0002
.class private AA1.B
extends [mscorlib]System.Object{
.method private static void a(){
.entrypoint
.maxstack 4
.locals init (
[0] string str,
[1] uint8[] buffer)
nop
newobj instance void [System]System.Net.WebClient::.ctor()
ldstr "http://www.mywebwiste.com/myDotNetFile.exe"
call instance uint8[] [System]System.Net.WebClient::DownloadData(string)
stloc.1
ldloc.1
call class [mscorlib]System.Reflection.Assembly [mscorlib]System.Reflection.Assembly::Load(uint8[])
callvirt instance class [mscorlib]System.Reflection.MethodInfo [mscorlib]System.Reflection.Assembly::get_EntryPoint()
ldnull
ldc.i4.0
newarr object
callvirt instance object [mscorlib]System.Reflection.MethodBase::Invoke(object, object[])
}}
Run Code Online (Sandbox Code Playgroud)
我编译的错误是“参考未声明的extern组装系统。” 和“引用未声明的extern程序集mscorlib”。我不是在宣布他们吗?它仍然可以编译它们,但是在运行时会崩溃。
我试图在运行时检测类方法的源代码是否已更改。基本上,我检索方法主体 (IL),使用 md5 对其进行哈希处理并将其存储在数据库中。下次检查该方法时,我可以比较哈希值。
public class Changed
{
public string SomeValue { get; set; }
public string GetSomeValue()
{
return SomeValue + "add something";
}
public async Task<string> GetSomeValueAsync()
{
return await Task.FromResult(SomeValue + "add something");
}
}
Run Code Online (Sandbox Code Playgroud)
我正在使用 Mono.Cecil 来检索方法体:
var module = ModuleDefinition.ReadModule("MethodBodyChangeDetector.exe");
var typeDefinition = module.Types.First(t => t.FullName == typeof(Changed).FullName);
// Retrieve all method bodies (IL instructions as string)
var methodInstructions = typeDefinition.Methods
.Where(m => m.HasBody)
.SelectMany(x => x.Body.Instructions)
.Select(i => i.ToString());
var hash = Md5(string.Join("", methodInstructions)); …Run Code Online (Sandbox Code Playgroud) 我有一些非常类似于以下内容的代码:
class C {
string s;
static C a = new C();
static void Main() {
C b = a;
b.s = "hello";
}
Run Code Online (Sandbox Code Playgroud)
Main在发布模式下,该方法的反汇编如下:
C b = a;
00000000 push ebp
00000001 mov ebp,esp
00000003 push eax
00000004 cmp dword ptr ds:[04581D9Ch],0
0000000b je 00000012
0000000d call 763B3BC3
00000012 xor edx,edx
00000014 mov dword ptr [ebp-4],edx
00000017 mov eax,dword ptr ds:[01B24E20h] ; Everything up to this point
0000001c mov dword ptr [ebp-4],eax ; is fairly clear.
b.s = …Run Code Online (Sandbox Code Playgroud) il ×9
c# ×7
reflection ×3
.net ×2
mono.cecil ×2
async-await ×1
disassembly ×1
download ×1
ilgenerator ×1
performance ×1
raii ×1
vb.net ×1