C#从MethodInfo.Getmethod()中进行委托转换
我正在写一个对函数进行数学运算的程序。我希望用户输入函数,所以我编写了一个类,该类用所需的方法生成scource代码,编译它并将该方法保存为委托。这个方法被传递给我的另一个类的构造函数,它存储在委托中。 问题是:它不起作用。出现InvalidCastException (我这样做是为了不必编写自己的数学解析器。像math.Pow(x,2)*math.Sin(x)这样的表达式应该可以,不需要像x^2*Sin(x)这样的东西来工作) [已编辑] 现在我用C#从MethodInfo.Getmethod()中进行委托转换,c#,.net,C#,.net,我正在写一个对函数进行数学运算的程序。我希望用户输入函数,所以我编写了一个类,该类用所需的方法生成scource代码,编译它并将该方法保存为委托。这个方法被传递给我的另一个类的构造函数,它存储在委托中。 问题是:它不起作用。出现InvalidCastException (我这样做是为了不必编写自己的数学解析器。像math.Pow(x,2)*math.Sin(x)这样的表达式应该可以,不需要像x^2*Sin(x)这样的东西来工作) [已编辑] 现在我用 Func<decimal, decim
Func<decimal, decimal>
Func
在传递委托的位置(传递给类函数的构造函数:公共函数(func f,decimal l)):
Func function=newfunc(MathParser.MakeExpr(inputTextBox.Text));
F=新功能(功能,l);
生成所需委托的内容:
using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Reflection;
using System.Windows.Forms;
namespace Furry
{
internal class MathParser
{
private static string begin =
@"using System;
namespace Parser
{
public delegate decimal func(decimal x);
public static class LambdaCreator
{
public static decimal Create()
{
return (x)=>";
private static string end = @";
}
}
}";
public static Func<decimal, decimal> MakeExpr(string Expr)
{
string middle = Expr;
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters
{
GenerateInMemory = true
};
parameters.ReferencedAssemblies.Add("System.dll");
CompilerResults results = provider.CompileAssemblyFromSource(parameters, begin + middle + end);
Type cls = results.CompiledAssembly.GetType("Parser.LambdaCreator");
MethodInfo method = cls.GetMethod("Create", BindingFlags.Static | BindingFlags.Public);
Delegate f = method.Invoke(null, null) as Delegate;
//MessageBox.Show(f.DynamicInvoke(5m).ToString()); doesn't work
return (Func<decimal, decimal>)f;
}
}
使用Microsoft.CSharp;
使用制度;
使用System.CodeDom.Compiler;
运用系统反思;
使用System.Windows.Forms;
名称空间毛茸茸的
{
内部类数学分析器
{
私有静态字符串开始=
@“使用系统;
名称空间分析器
{
公共委托十进制函数(十进制x);
公共静态类LambdaCreator
{
公共静态十进制创建()
{
返回值(x)=>”;
私有静态字符串end=@”;
}
}
}";
公共静态函数MakeExpr(字符串Expr)
{
字符串中间=Expr;
CSharpCodeProvider provider=新的CSharpCodeProvider();
CompilerParameters参数=新的CompilerParameters
{
GenerateInMemory=true
};
parameters.referencedAssembly.Add(“System.dll”);
CompilerResults results=provider.compileAsemblyFromSource(参数,开始+中间+结束);
类型cls=results.CompiledAssembly.GetType(“Parser.LambdaCreator”);
MethodInfo method=cls.GetMethod(“创建”,BindingFlags.Static | BindingFlags.Public);
委托f=方法。作为委托调用(null,null);
//MessageBox.Show(f.DynamicInvoke(5m.ToString());不工作
返回(Func)f;
}
}
}
还试图援引:
Func<decimal, decimal> f = method.Invoke(null, null) as Func<decimal, decimal>;
Func f=method.Invoke(null,null)为Func;
现在发生FileNotFoundException。
FileNotFoundException:未能加载文件或程序集“file:///C:\“用户\Adefe\AppData\Local\Temp\trd2ig0g.dll”或其依赖项之一。找不到指定的文件。解决方案:
MathParser类:
using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Reflection;
namespace Furry
{
internal class MathParser
{
private static string begin =
@"using System;
namespace Parser
{
public delegate decimal func(decimal x);
public static class LambdaCreator
{
public static Func<decimal, decimal> Create()
{
return (x)=>";
private static string end = @";
}
}
}";
public static Func<decimal, decimal> MakeExpr(string Expr)
{
string middle = Expr;
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters
{
GenerateInMemory = true
};
parameters.ReferencedAssemblies.Add("System.dll");
CompilerResults results = provider.CompileAssemblyFromSource(parameters, begin + middle + end);
Type cls = results.CompiledAssembly.GetType("Parser.LambdaCreator");
MethodInfo method = cls.GetMethod("Create", BindingFlags.Static | BindingFlags.Public);
Delegate f = method.Invoke(null, null) as Delegate;
return (Func<decimal, decimal>)f;
}
}
}
使用Microsoft.CSharp;
使用制度;
使用System.CodeDom.Compiler;
运用系统反思;
名称空间毛茸茸的
{
内部类数学分析器
{
私有静态字符串开始=
@“使用系统;
名称空间分析器
{
公共委托十进制函数(十进制x);
公共静态类LambdaCreator
{
公共静态函数Create()
{
返回值(x)=>”;
私有静态字符串end=@”;
}
}
}";
公共静态函数MakeExpr(字符串Expr)
{
字符串中间=Expr;
CSharpCodeProvider provider=新的CSharpCodeProvider();
CompilerParameters参数=新的CompilerParameters
{
GenerateInMemory=true
};
parameters.referencedAssembly.Add(“System.dll”);
CompilerResults results=provider.compileAsemblyFromSource(参数,开始+中间+结束);
类型cls=results.CompiledAssembly.GetType(“Parser.LambdaCreator”);
MethodInfo method=cls.GetMethod(“创建”,BindingFlags.Static | BindingFlags.Public);
委托f=方法。作为委托调用(null,null);
返回(Func)f;
}
}
}
begin中定义的func
类型与C#code中定义的func
类型不同。为什么不使用一个两者都可以访问的类型,例如Func
?另一个选项是将Create
方法定义为publicstaticdecimalcreate(decimalx)
(而不是让它返回委托),只需调用它上述任何方法都不起作用。十进制函数根本不起作用。发生FileNotFoundException。请您的问题显示您尝试过的代码,否则我们无法帮助您将Create
方法定义为decimal Create()
,但您正在尝试将其返回值强制转换为Func
。这是我提出的两个不同建议的奇怪的错误组合。如果Create
方法返回委托,则其返回类型应为Func
:这当前导致生成的C#代码无法编译,导致FileNotFound错误。如果将Create
方法改为接受decimal
并返回decimal
,则其返回类型显然是decimal
,因此不应将其大小写为Func
using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Reflection;
namespace Furry
{
internal class MathParser
{
private static string begin =
@"using System;
namespace Parser
{
public delegate decimal func(decimal x);
public static class LambdaCreator
{
public static Func<decimal, decimal> Create()
{
return (x)=>";
private static string end = @";
}
}
}";
public static Func<decimal, decimal> MakeExpr(string Expr)
{
string middle = Expr;
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters
{
GenerateInMemory = true
};
parameters.ReferencedAssemblies.Add("System.dll");
CompilerResults results = provider.CompileAssemblyFromSource(parameters, begin + middle + end);
Type cls = results.CompiledAssembly.GetType("Parser.LambdaCreator");
MethodInfo method = cls.GetMethod("Create", BindingFlags.Static | BindingFlags.Public);
Delegate f = method.Invoke(null, null) as Delegate;
return (Func<decimal, decimal>)f;
}
}
}