【问题标题】:Convert string to anonymous method将字符串转换为匿名方法
【发布时间】:2011-11-28 16:26:13
【问题描述】:

考虑这段代码:

    static void Main(string[] args)
    {
        var persons = new List<Person>
                          {
                              new Person("Name1", "Surname1", 30),
                              new Person("Name2", "Surname2", 20),
                              new Person("Name3", "Surname3", 10)
                          };

        var filters = new List<Func<Person, bool>>
                          {
                              p => p.Age > 10,
                              p => p.Surname.Contains("2")
                          };

        var personsFiltered = new List<Person>(persons);
        foreach (var filter in filters)
        {
            personsFiltered = personsFiltered.Where(filter).ToList();
        }

        foreach (var person in personsFiltered)
        {
            Console.WriteLine(person);
        }

        Console.ReadKey();
    }
}

class Person
{
    public string Name { get; private set; }
    public string Surname { get; private set; }
    public int Age { get; private set; }

    public Person(string name, string surname, int age)
    {
        Name = name;
        Surname = surname;
        Age = age;
    }

    public override string ToString()
    {
        return String.Format("Name:{0}, Surname:{1}, Age:{2}", Name, Surname, Age);
    }
}

是否可以将过滤器作为字符串参数传递,以便用户可以创建自定义过滤器?例如,我的示例中的 filters 列表最初为空,用户将提供字符串 "p => p.Age > 10" 和 "p => p.Surname.Contains(\"2")"?

【问题讨论】:

  • 也许在您在代码中使用它们之前将字符串版本反序列化回一个对象?编辑:该字符串不起作用,需要采用序列化格式。
  • 您可以使用动态 Linq 扩展 stackoverflow.com/questions/3991108/…
  • 当你的用户给你p =&gt; (p.Age / 0) == 2? (半开玩笑......)

标签: c#


【解决方案1】:

您有两种选择允许用户为您的应用程序编写代码:脚本引擎和动态编译。

LUA

您可以集成像 Lua 这样的脚本引擎(我发现这很容易):/technical/game-programming/using-lua-with-c-r2275">http://www.gamedev.net/page/resources //技术/游戏编程/使用-lua-with-c-r2275

您需要创建一个 Lua 环境,设置用户脚本使用的变量,然后从该环境中读取变量。我使用这种方法构建了一个部分脚本化的打印模板引擎,它运行良好。 C# 的 LuaInterface 非常直观和简单。

动态编译

另一种选择是实现动态编译(有点麻烦,但更强大):http://www.codeproject.com/KB/dotnet/DynamicCompileAndRun.aspx

您需要创建一个框架类并连接一个字符串以将用户的脚本包含在实现某个接口的类中。类似的东西:

class ClientScript : IScriptFramework {
    public override String Method(Object object) {
        return %CLIENT_CODE%;
    }
}

假设 IScriptFramework 声明了 Method,您可以将此类的实例存储到 IScriptFramework 并调用 Method 而无需任何反射。只需将此代码存储在资源中,通过将 %CLIENT_CODE% 替换为实际代码(如 object.ToString())生成最终源代码,然后按照我链接的帖子中的说明在内存中编译它。

我在测试框架中使用了动态编译,虽然语法比 Lua 之类的脚本引擎更严格,但它运行良好。

编辑:Viacheslav Smityukh 是对的,有一个框架可以为您完成动态编译 LINQ 查询的艰巨工作。不久前我读过它,但在看到他的评论之前我没有想到。这可能是最适合您的方法:http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

【讨论】:

    猜你喜欢
    • 2011-12-23
    • 1970-01-01
    • 2021-07-21
    • 2011-01-19
    • 2016-10-11
    • 2013-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多