gpt4 book ai didi

c# - C#中的函数指针

转载 作者:可可西里 更新时间:2023-11-01 08:16:06 26 4
gpt4 key购买 nike

我想在某些方面(或两者)DelegateMethodInfo 符合这个标题。但是,两者都没有提供我正在寻找的语法优美性。所以,简而言之,有什么方法可以写出以下内容:

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

我不能使用实体委托(delegate)(即,使用 delegate 关键字来声明委托(delegate)类型),因为在运行时之前无法知道确切的参数列表。作为引用,这是我目前在 LINQPad 中玩弄的内容,其中 B 将(主要)是用户生成的代码,Main 也是如此,因此为了美观我的用户,我正在尝试删除 .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.");
}
}

最佳答案

你说你想保持参数的数量和类型是开放的,但你可以用委托(delegate)来做到这一点:

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

这与您目前拥有的完全相同。试试这个:

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

return null;
};

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

您可以将实例方法委托(delegate)视为与您的 Function 类非常相似:一个对象和一个 MethodInfo。所以没有必要重写它。

此外,C 和 C++ 中的函数指针与您的需求并不相近:它们不能绑定(bind)到对象实例函数,而且它们是静态类型的,而不是动态类型的。

如果你想在 DynamicFunc 委托(delegate)中“包装”任何其他方法,试试这个:

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,但如果它是实例方法,我将传递对象绑定(bind)到。 Program 恰好是我定义静态方法的类。

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

关于c# - C#中的函数指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1184329/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com