C# 从字符串加载方法体?

C# 从字符串加载方法体?,c#,reflection,configuration,C#,Reflection,Configuration,对于非常特殊的情况,我希望能够在配置条目中存储C#代码,并在运行时使用此代码填充空函数。例如,假设在初始运行时,我开始使用如下方法: bool Evaluate(int number) { return false; } 我有一个如下所示的配置条目: <add key="EvaluateCode" value="if (number > 5) { return true; } else { return false; }"/> bool Evaluate(int nu

对于非常特殊的情况,我希望能够在配置条目中存储C#代码,并在运行时使用此代码填充空函数。例如,假设在初始运行时,我开始使用如下方法:

bool Evaluate(int number)
{
   return false;
}
我有一个如下所示的配置条目:

<add key="EvaluateCode" value="if (number > 5) { return true; } else { return false; }"/>
bool Evaluate(int number)
{
   if (number > 5) { return true; } else { return false; }
}
在进行这个“替换”之后,Evaluate函数应该按照代码的指示进行操作,就像没有动态加载代码一样

我怎么能用C#实现这个呢


奖励:实施此功能的风险是什么?我如何降低这些风险?

本质上你是在要求在运行时编译c代码的能力,这是可能的,并且被描述了

本质上你是在要求在运行时编译c代码的能力,这是可能的,并且被描述了

本质上你是在要求在运行时编译c代码的能力,这是可能的,并且被描述了

本质上,您要求在运行时编译c代码,这是可能的,并且被描述了

这听起来很有趣。。所以我决定试试

没有必要投票。。只是在这里弹出这个,以便将来我可以引用它:)

鉴于以下类别:

class DynamicMethodTest {
    private MethodInfo _methodToCall;
    private object _obj;

    public void PerformInjection(string newBody) {
        using (var codeProvider =
       new Microsoft.CSharp.CSharpCodeProvider()) {
            var res = codeProvider.CompileAssemblyFromSource(
                new System.CodeDom.Compiler.CompilerParameters() {
                    GenerateInMemory = true
                },
                "public class StubClass { public bool Evaluate(int number) { " + newBody + " }}"
            );

            var type = res.CompiledAssembly.GetType("StubClass");

            _obj = Activator.CreateInstance(type);

            _methodToCall = _obj.GetType().GetMethod("Evaluate");
        }
    }

    public bool Evaluate(int number) {
        if (_methodToCall != null)
            return (bool)_methodToCall.Invoke(_obj, new object[] { number });

        return false;
    }
}
我们可以这样做:

public class Program {
    public static void Main() {
        var dynamicTest = new DynamicMethodTest();

        Console.WriteLine(dynamicTest.Evaluate(15)); // False

        dynamicTest.PerformInjection("if (number > 5) { return true; } else { return false; }");

        Console.WriteLine(dynamicTest.Evaluate(15)); // True

        Console.Read();
    }

}
这导致:

False
True

作为输出。基本上,在“注入”(不是真正的注入..更像是一个fascade)之前,方法返回false。“注入”后返回true(如预期的那样)。

这听起来很有趣。。所以我决定试试

没有必要投票。。只是在这里弹出这个,以便将来我可以引用它:)

鉴于以下类别:

class DynamicMethodTest {
    private MethodInfo _methodToCall;
    private object _obj;

    public void PerformInjection(string newBody) {
        using (var codeProvider =
       new Microsoft.CSharp.CSharpCodeProvider()) {
            var res = codeProvider.CompileAssemblyFromSource(
                new System.CodeDom.Compiler.CompilerParameters() {
                    GenerateInMemory = true
                },
                "public class StubClass { public bool Evaluate(int number) { " + newBody + " }}"
            );

            var type = res.CompiledAssembly.GetType("StubClass");

            _obj = Activator.CreateInstance(type);

            _methodToCall = _obj.GetType().GetMethod("Evaluate");
        }
    }

    public bool Evaluate(int number) {
        if (_methodToCall != null)
            return (bool)_methodToCall.Invoke(_obj, new object[] { number });

        return false;
    }
}
我们可以这样做:

public class Program {
    public static void Main() {
        var dynamicTest = new DynamicMethodTest();

        Console.WriteLine(dynamicTest.Evaluate(15)); // False

        dynamicTest.PerformInjection("if (number > 5) { return true; } else { return false; }");

        Console.WriteLine(dynamicTest.Evaluate(15)); // True

        Console.Read();
    }

}
这导致:

False
True

作为输出。基本上,在“注入”(不是真正的注入..更像是一个fascade)之前,方法返回false。“注入”后返回true(如预期的那样)。

这听起来很有趣。。所以我决定试试

没有必要投票。。只是在这里弹出这个,以便将来我可以引用它:)

鉴于以下类别:

class DynamicMethodTest {
    private MethodInfo _methodToCall;
    private object _obj;

    public void PerformInjection(string newBody) {
        using (var codeProvider =
       new Microsoft.CSharp.CSharpCodeProvider()) {
            var res = codeProvider.CompileAssemblyFromSource(
                new System.CodeDom.Compiler.CompilerParameters() {
                    GenerateInMemory = true
                },
                "public class StubClass { public bool Evaluate(int number) { " + newBody + " }}"
            );

            var type = res.CompiledAssembly.GetType("StubClass");

            _obj = Activator.CreateInstance(type);

            _methodToCall = _obj.GetType().GetMethod("Evaluate");
        }
    }

    public bool Evaluate(int number) {
        if (_methodToCall != null)
            return (bool)_methodToCall.Invoke(_obj, new object[] { number });

        return false;
    }
}
我们可以这样做:

public class Program {
    public static void Main() {
        var dynamicTest = new DynamicMethodTest();

        Console.WriteLine(dynamicTest.Evaluate(15)); // False

        dynamicTest.PerformInjection("if (number > 5) { return true; } else { return false; }");

        Console.WriteLine(dynamicTest.Evaluate(15)); // True

        Console.Read();
    }

}
这导致:

False
True

作为输出。基本上,在“注入”(不是真正的注入..更像是一个fascade)之前,方法返回false。“注入”后返回true(如预期的那样)。

这听起来很有趣。。所以我决定试试

没有必要投票。。只是在这里弹出这个,以便将来我可以引用它:)

鉴于以下类别:

class DynamicMethodTest {
    private MethodInfo _methodToCall;
    private object _obj;

    public void PerformInjection(string newBody) {
        using (var codeProvider =
       new Microsoft.CSharp.CSharpCodeProvider()) {
            var res = codeProvider.CompileAssemblyFromSource(
                new System.CodeDom.Compiler.CompilerParameters() {
                    GenerateInMemory = true
                },
                "public class StubClass { public bool Evaluate(int number) { " + newBody + " }}"
            );

            var type = res.CompiledAssembly.GetType("StubClass");

            _obj = Activator.CreateInstance(type);

            _methodToCall = _obj.GetType().GetMethod("Evaluate");
        }
    }

    public bool Evaluate(int number) {
        if (_methodToCall != null)
            return (bool)_methodToCall.Invoke(_obj, new object[] { number });

        return false;
    }
}
我们可以这样做:

public class Program {
    public static void Main() {
        var dynamicTest = new DynamicMethodTest();

        Console.WriteLine(dynamicTest.Evaluate(15)); // False

        dynamicTest.PerformInjection("if (number > 5) { return true; } else { return false; }");

        Console.WriteLine(dynamicTest.Evaluate(15)); // True

        Console.Read();
    }

}
这导致:

False
True

作为输出。基本上,在“注入”(不是真正的注入..更像是一个fascade)之前,方法返回false。“注入”后,它返回真值(如预期的那样)。

我很惊讶我之前没有遇到这个问题。谢谢你指给我看。我很惊讶我之前没有看到这个。谢谢你指给我看。我很惊讶我之前没有看到这个。谢谢你指给我看。我很惊讶我之前没有看到这个。谢谢你指给我看,西蒙。这正是我要找的!这是对我的问题的一个直接回答,在我试图做的事情上对我帮助很大。谢谢你,西蒙。这正是我要找的!这是对我的问题的一个直接回答,在我试图做的事情上对我帮助很大。谢谢你,西蒙。这正是我要找的!这是对我的问题的一个直接回答,在我试图做的事情上对我帮助很大。谢谢你,西蒙。这正是我要找的!这是对我的问题的一个直接回答,在我试图做的事情上对我帮助很大。非常感谢。