大多数情况下,C#委托已将对象与成员函数一起存储起来非常方便.但有没有办法,存储 - 并作为参数传递 - 只有成员函数本身,就像C++中的旧指针指向成员函数一样?
如果描述不清楚,我给出一个自包含的例子.并且,是的,在示例中,传递成员函数的坚持是完全没有意义的,但我有更严肃的用途.
class Foo {
public int i { get; set; }
/* Can this be done?
public static int Apply (Foo obj, ???? method, int j) {
return obj.method (j);
}
*/
public static int ApplyHack (Foo obj, Func<int, int> method, int j) {
return (int) method.Method.Invoke (obj, new object [] { j });
}
public static readonly Foo _ = new Foo (); // dummy object for ApplyHack
public int Multiply (int j) {
return i * j;
}
public int Add (int j) {
return i + j;
}
}
class Program {
static void Main (string [] args) {
var foo = new Foo { i = 7 };
Console.Write ("{0}\n", Foo.ApplyHack (foo, Foo._.Multiply, 5));
Console.Write ("{0}\n", Foo.ApplyHack (foo, Foo._.Add, 5));
Console.ReadKey ();
}
}
Run Code Online (Sandbox Code Playgroud)
你知道,我发现的唯一的解决方法是相当丑陋而且可能很慢.
the*_*oop 10
你想要的是一个叫做开放实例委托的东西.我在博客上写过这些文章
基本上,您可以创建实例方法的委托而不将其绑定到特定实例,并在调用它时指定要在其上使用它的实例:
class Foo {
public int i { get; set; }
public int Multiply (int j) {
return i * j;
}
public int Add (int j) {
return i + j;
}
}
class Program {
static void Main (string [] args) {
Func<Foo, int, int> multiply = (Func<Foo, int, int>)Delegate.CreateDelegate(typeof(Func<Foo, int, int>), null, typeof(Foo).GetMethod("Multiply");
Func<Foo, int, int> add = (Func<Foo, int, int>)Delegate.CreateDelegate(typeof(Func<Foo, int, int>), null, typeof(Foo).GetMethod("Add");
var foo1 = new Foo { i = 7 };
var foo2 = new Foo { i = 8 };
Console.Write ("{0}\n", multiply(foo1, 5));
Console.Write ("{0}\n", add(foo1, 5));
Console.Write ("{0}\n", multiply(foo2, 5));
Console.Write ("{0}\n", add(foo2, 5));
Console.ReadKey ();
}
}
Run Code Online (Sandbox Code Playgroud)
拿你现有的代码:
public static int ApplyHack (Foo obj, Func<int, int> method, int j) {
return (int) method.Method.Invoke (obj, new object [] { j });
}
Run Code Online (Sandbox Code Playgroud)
你可以这样做:
public static int ApplyHack (Foo obj, Func<int, int> method, int j) {
var func = (Func<int,int>)Delegate.CreateDelegate(typeof(Func<int,int>), obj, method.Method);
return func(j);
}
Run Code Online (Sandbox Code Playgroud)
这将在方法和新对象周围创建一个新委托.举个例子:
public static int Apply (Foo obj, ???? method, int j) {
return obj.method (j);
}
Run Code Online (Sandbox Code Playgroud)
您正在寻找的类型是System.Reflection.MethodInfo,它看起来像这样:
public static int Apply (Foo obj, MethodInfo method, int j) {
var func = (Func<int,int>)Delegate.CreateDelegate(typeof(Func<int,int>), obj, method);
return func(i);
}
Run Code Online (Sandbox Code Playgroud)
请注意,在为每次调用分配委托时,我相信这仍然比使用反射更快,因为您不必使用框函数输入/输出,也不会将其存储在object[]数组中.
假设您正在使用C#2.0或更高版本,并且可以访问匿名委托,您可以通过在存储点将函数包装在匿名委托中来实现:
class Foo
{
public Foo(int v)
{
this.v = v;
}
int v;
public int Multiply(int x)
{
return v * x;
}
public int Add(int x)
{
return v+x;
}
delegate int NewFunctionPointer(Foo, int);
delegate int OldDelegateStyle(int);
static void Example()
{
Foo f = new Foo(2);
Foo f2 = new Foo(3);
// instead of this, which binds an instance
OldDelegateStyle oldMul = f.Multiply;
// You have to use this
NewFunctionPointer mul = delegate(Foo f, int x) { return f.Multiply(x); }
NewFunctionPointer add = delegate(Foo f, int x) { return f.Add(x); }
// But can now do this
mul(f, 4); // = 8
add(f2, 1); // = 3
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7899 次 |
| 最近记录: |