Universal Func<> type in c#

半腔热情 提交于 2019-12-21 05:31:42

问题


I'm writing a small Lisp interpreter in C#, and it's basically working already. Currently I'm using an interface to represent functions:

public interface LispFunction
{
    object Apply(ArrayList parameters);
}

The interface is implemented by multiple classes for internal (standard) functions, lambdas, macro expansion, calling methods in .net objects via reflection and so on. Please note that speed is NOT an issue here, just the joy of getting the interpreter to, and use it at, work.

Now I'd like my little Lisp to accept arbitrary C# lambdas to be used within the interpreter, like this:

Lisp foo = new Lisp();
foo.GlobalEnvironment.AddFunction("test", (bool a, int b) => a ? b : "whoops");
foo.Eval(foo.Read("(test #t 5)")); // Should evaluate to (object) 5

First thing that came to my mind was using Func<...>, but I'd have to use lots of overloaded methods for Func<a>, Func<a, b>, Func<a, b, c> and so on.

Is there a possibility in C# to accept arbitrary lambdas to be called via reflection later?


回答1:


Is there a possibility in C# to accept arbitrary lambdas to be called via reflection later?

Well you can write a method to take an arbitrary delegate:

public void AddFunction(string name, Delegate function)

However, the conversion from a lambda expression has to be as a specific delegate, so you'd need:

Func<bool, string, string> function = (a, b) => a ? b : "whoops"
foo.GlobalEnvironment.AddFunction("test", function);

Or cast within the call:

foo.GlobalEnvironment.AddFunction("test",
    (Func<bool, string, string>)((a, b) => a ? b : "whoops"));

You could put all the overloading in one place, keeping AddFunction entirely general, but having a static class like this (a bit like Tuple):

public static class Func
{
    public Func<TResult> Create(Func<TResult> function) { return function; }

    public Func<T1, TResult> Create(Func<T1, TResult> function)
    {
        return function;
    }

    public Func<T1, T2, TResult> Create(Func<T1, T2, TResult> function)
    {
        return function;
    }

    // etc
}

This class basically just exists for convenience. You'd then call:

foo.GlobalEnvironment.AddFunction("test",
    Func.Create((bool a, string b) => a ? b : "whoops"));


来源:https://stackoverflow.com/questions/10347634/universal-func-type-in-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!