函数指针在C# [英] Function pointers in C#

查看:135
本文介绍了函数指针在C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为在某些方面(或两者)委托 MethodInfo 有资格获得此标题。但是,既不提供我正在寻找的句法好感。那么简而言之,有一些方法我可以写下列内容:

I suppose in some ways either (or both) Delegate or MethodInfo qualify for this title. However, neither provide the syntactic niceness that I'm looking for. So, in short, Is there some way that I can write the following:

FunctionPointer foo = // whatever, create the function pointer using mechanisms
foo();

我无法使用固定的委托(即使用 / code>关键字来声明一个委托类型),因为在运行时没有办法知道确切的参数列表。作为参考,这里是我一直在LINQPad目前使用的东西,其中 B 将(主要是)用户生成的代码,所以 Main ,因此对于我的用户来说,我试图删除 .Call

I can't use a solid delegate (ie, using the delegate keyword to declare a delegate type) because there is no way of knowing till runtime the exact parameter list. For reference, here's what I've been toying with in LINQPad currently, where B will be (mostly) user generated code, and so will Main, and hence for nicety to my users, I'm trying to remove the .Call:

void Main()
{
    A foo = new B();
    foo["SomeFuntion"].Call();
}

// Define other methods and classes here
interface IFunction {
    void Call();
    void Call(params object[] parameters);
}

class A {
    private class Function : IFunction {
        private MethodInfo _mi;
        private A _this;
        public Function(A @this, MethodInfo mi) {
            _mi = mi;
            _this = @this;
        }

        public void Call() { Call(null); }
        public void Call(params object[] parameters) {
            _mi.Invoke(_this, parameters);
        }
    }

    Dictionary<string, MethodInfo> functions = new Dictionary<string, MethodInfo>();

    public A() {
        List<MethodInfo> ml = new List<MethodInfo>(this.GetType().GetMethods());
        foreach (MethodInfo mi in typeof(Object).GetMethods())
        {
            for (int i = 0; i < ml.Count; i++)
            {
                if (ml[i].Name == mi.Name)
                    ml.RemoveAt(i);
            }
        }

        foreach (MethodInfo mi in ml)
        {
            functions[mi.Name] = mi;
        }
    }

    public IFunction this[string function] {
        get { 
            if (!functions.ContainsKey(function))
                throw new ArgumentException();

            return new Function(this, functions[function]);
        }
    }
}

sealed class B : A {
    public void SomeFuntion() {
        Console.WriteLine("SomeFunction called.");
    }
}


推荐答案

你说你想保留参数的数量和类型打开,但是你可以用delgate来实现:

You say you want to keep the number and type of parameters open, but you can do that with a delgate:

public delegate object DynamicFunc(params object[] parameters);

这与您目前完全一样。尝试这样:

This is exactly the same thing you currently have. Try this:

class Program
{
    static void Main(string[] args)
    {
        DynamicFunc f = par =>
                        {
                            foreach (var p in par)
                                Console.WriteLine(p);

                            return null;
                        };

        f(1, 4, "Hi");
    }
}

您可以将一个实例方法委托视为非常类似于您的函数类:一个对象,一个 MethodInfo 。所以没有必要重写它。

You can think of an instance-method delegate as very similar to your Function class: an object an a MethodInfo. So there's no need to rewrite it.

C和C ++中的函数指针不再靠近你所需要的:它们不能绑定到对象实例函数,并且它们是静态类型的,而不是动态类型的。

Also function pointers in C and C++ are not any closer to what you need: they cannot be bound to an object instance and function, and also they are statically typed, not dynamically typed.

如果要在DynamicFunc委托中包装任何其他方法,请尝试此:

If you want to "wrap" any other method in a DynamicFunc delegate, try this:

public static DynamicFunc MakeDynamicFunc(object target, MethodInfo method)
{
    return par => method.Invoke(target, par);
}

public static void Foo(string s, int n)    
{
    Console.WriteLine(s);
    Console.WriteLine(n);
}

然后:

DynamicFunc f2 = MakeDynamicFunc(null, typeof(Program).GetMethod("Foo"));

f2("test", 100);

请注意,我使用静态方法 Foo 所以我通过 null 为实例,但如果它是一个实例方法,我会传递对象绑定到。 程序恰好是我的静态方法定义的类。

Note that I'm using a static method Foo so I pass null for the instance, but if it was an instance method, I'd be passing the object to bind to. Program happens to be the class my static methods are defined in.

当然,如果你传递错误的参数类型,那么你在运行时会得到错误。我可能会寻找一种设计程序的方法,以便尽可能多地在编译时捕获类型信息。

Of course, if you pass the wrong argument types then you get errors at runtime. I'd probably look for a way to design your program so that as much type information is captured at compile time as possible.

这篇关于函数指针在C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆