C#从MethodInfo.Getmethod()中进行委托转换

C#从MethodInfo.Getmethod()中进行委托转换,c#,.net,C#,.net,我正在写一个对函数进行数学运算的程序。我希望用户输入函数,所以我编写了一个类,该类用所需的方法生成scource代码,编译它并将该方法保存为委托。这个方法被传递给我的另一个类的构造函数,它存储在委托中。 问题是:它不起作用。出现InvalidCastException (我这样做是为了不必编写自己的数学解析器。像math.Pow(x,2)*math.Sin(x)这样的表达式应该可以,不需要像x^2*Sin(x)这样的东西来工作) [已编辑] 现在我用 Func<decimal, decim

我正在写一个对函数进行数学运算的程序。我希望用户输入函数,所以我编写了一个类,该类用所需的方法生成scource代码,编译它并将该方法保存为委托。这个方法被传递给我的另一个类的构造函数,它存储在委托中。 问题是:它不起作用。出现InvalidCastException

(我这样做是为了不必编写自己的数学解析器。像math.Pow(x,2)*math.Sin(x)这样的表达式应该可以,不需要像x^2*Sin(x)这样的东西来工作)

[已编辑] 现在我用

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;
    }
  }
}