Mat*_*ley 12 c# reflection delegates
我想在某些方面(或两者)Delegate或MethodInfo有资格获得这个头衔.但是,它们都没有提供我正在寻找的语法上的好处.所以,简而言之,有什么方法可以写下面的内容:
FunctionPointer foo = // whatever, create the function pointer using mechanisms
foo();
Run Code Online (Sandbox Code Playgroud)
我不能使用可靠的委托(即,使用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.");
}
}
Run Code Online (Sandbox Code Playgroud)
Dan*_*ker 29
你说你想保持参数的数量和类型是开放的,但你可以用delgate做到这一点:
public delegate object DynamicFunc(params object[] parameters);
Run Code Online (Sandbox Code Playgroud)
这与您目前拥有的完全相同.试试这个:
class Program
{
static void Main(string[] args)
{
DynamicFunc f = par =>
{
foreach (var p in par)
Console.WriteLine(p);
return null;
};
f(1, 4, "Hi");
}
}
Run Code Online (Sandbox Code Playgroud)
您可以将实例方法委托视为与您的Function类非常相似:对象和a MethodInfo.所以没有必要重写它.
C和C++中的函数指针也没有更接近你需要的东西:它们不能绑定到对象实例和函数,它们也是静态类型的,不是动态类型的.
如果要在DynamicFunc委托中"包装"任何其他方法,请尝试以下操作:
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);
}
Run Code Online (Sandbox Code Playgroud)
然后:
DynamicFunc f2 = MakeDynamicFunc(null, typeof(Program).GetMethod("Foo"));
f2("test", 100);
Run Code Online (Sandbox Code Playgroud)
请注意,我正在使用静态方法,Foo所以我传递null给实例,但如果它是一个实例方法,我将传递对象绑定到.Program碰巧是我的静态方法定义的类.
当然,如果传递错误的参数类型,那么在运行时会出现错误.我可能会寻找一种设计程序的方法,以便尽可能在编译时捕获尽可能多的类型信息.
| 归档时间: |
|
| 查看次数: |
11743 次 |
| 最近记录: |