Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 转换反射。发射到Roslyn_C#_Roslyn_Reflection.emit - Fatal编程技术网

C# 转换反射。发射到Roslyn

C# 转换反射。发射到Roslyn,c#,roslyn,reflection.emit,C#,Roslyn,Reflection.emit,我需要将使用Reflection.Emit的现有代码转换为Roslyn 我目前的代码基本上是这样的: var assemblyName = new AssemblyName("AssemblyName"); var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save); var builder = assemblyBuilder.Defi

我需要将使用Reflection.Emit的现有代码转换为Roslyn

我目前的代码基本上是这样的:

var assemblyName = new AssemblyName("AssemblyName");
var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save);

var builder = assemblyBuilder.DefineDynamicModule("test", "test.dll");

var type = builder.DefineType("Entry", TypeAttributes.Public, typeof(object), null);

var method = type.DefineMethod("###Start_v1.4.3.0", MethodAttributes.Public | MethodAttributes.HideBySig);
method.SetReturnType(typeof(void));

var generator = method.GetILGenerator();

generator.Emit(OpCodes.Nop);
generator.Emit(OpCodes.Ret);

type.CreateType();

assemblyBuilder.Save(@"test.dll");
如您所见,有一个名为
Entry
的类,其方法名为
###Start_v1.4.3.0

我们已经用了7年多了,但是每次我们需要改变任何事情,这都是一件痛苦的事情,因为我们需要使用那些
发射的
,而且这不是小事

如果我们能让Roslyn来编译代码那就太好了:

public class Entry
{
    public void ###Start_v1.4.3.0()
    {
    }
}
但由于方法名无效,因此它无法工作

编译后的dll由第三方组件使用,它会查找要执行的类和方法名。我们试图联系开发人员以获得新版本,但没有成功

我认为Roslyn根本不会编译这个,但我相信可能有一种方法可以在以后将方法名从
Start()
重命名为
##Start#u v1.4.3.0()
。。。我只是不知道怎么做


欢迎提供任何帮助。

如果唯一的问题是非法的方法名,您可以轻松解决该问题

使用合法名称编译dll,然后有几种方法更改方法名称

使用
mono.cecil
非常简单

public void ChangeMethodName()
{
    //Before changing the method name
    var assem = Assembly.LoadFile(@"C:\temp\ClassLibrary1.dll");
    Console.WriteLine(
        assem.GetType("ClassLibrary1.Class1").
        GetMethod("Start", BindingFlags.Static | BindingFlags.Public).
        Invoke(null, null));

    // Change the name
    var module = ModuleDefinition.ReadModule(@"C:\temp\ClassLibrary1.dll");
    TypeDefinition myType = 
        module.Types.First(type => type.Name == "Class1");
    var method = myType.Methods.First(m => m.Name == "Start");
    method.Name = "###Start_v1.4.3.0";
    module.Write(@"C:\temp\ClassLibrary1_new.dll");

    //After changing the method name
    assem = Assembly.LoadFile(@"C:\temp\ClassLibrary1_new.dll");
    Console.WriteLine(
        assem.GetType("ClassLibrary1.Class1").
        GetMethod("###Start_v1.4.3.0",
                  BindingFlags.Static|BindingFlags.Public).
        Invoke(null, null));
}



public class Class1
{
    public static string Start()
    {
        return $"my name is {MethodBase.GetCurrentMethod().Name}";
    }
}

我想你可以使用and,或Cecil,在以后进行修补。也许你应该提出功能请求,使其具有允许任意成员名称的模式。CLR对这些名字没有任何问题,我认为Roslyn的任何东西都不会从仅仅允许这些名字打破。