我需要为某种类型的对象调用一个函数,但我希望调用者指定我调用哪个函数。
在 C++ 中,我可以像这样使用指向成员的指针:
Type (Properties::* getType1)() = &Properties::GetType1;
有任何 C# 等效项吗?
请勿使用函数数组或开关等任何技巧。即使在函数签名满足要求的情况下添加新函数,我也希望这个解决方案能够工作。
编辑: 正如我所读到的:委托就像 C++ 函数指针,但类型安全。
但是我需要成员函数指针。例如。在我的函数中,我获得了某个对象:
var properties = manager.GetProperties();
现在需要获得某种类型的属性:
var type1 = properties.GetType1();
但我需要这样的东西
var typeX = properties.GetTypeX();
获取此函数调用的用户请求类型。 TypeX 必须是什么?
Type1..N 有公共基类,我需要使用这个类。
在 C# 中,有 delegates 来指定要传递到某处的函数的签名。
你的代码应该尝试这样的事情:
class Program
{
static void Write(int i)
{
Console.Write(i);
}
static void Main(string[] args)
{
C c = new C { FunctionToExecute = Write };
c.SomeMethod(5);
}
}
delegate void D(int F);
class C
{
public D FunctionToExecute { get; set; }
public void SomeMethod(int arg)
{
FunctionToExecute(arg);
}
}
D 指定签名,FunctionToExecute 是指向要执行的内容的指针。
如果你想传递未知类型的对象,那么有泛型。或者我不明白你到底想要什么。这里提到的Action和Func是通用委托。
如果您正在寻找 C++ 中指向成员运算符的指针的等效项,其他答案不会给出完整答案。
在 C++ 中,您可以获取指向成员的指针(字段或方法,在OP的问题中它是一个方法),然后将其应用于定义该成员的类的任何实例以调用该方法或检索该字段那个例子。其中包括虚拟和非虚拟函数(这比最初看起来更聪明)。
当用于捕获本地状态(可能包括特定的 this 指针)时,委托更像是直接函数指针(当与静态函数一起使用时,按照此处的其他答案)或闭包(想想 std::function )。这并不是说委托不是答案的一部分,而是仅在以其他地方尚未详细说明的特定方式使用时。
对于如何在 C# 中实际模拟指向成员的指针的问题,有四种可能的答案:
来自调用所需成员的对象类型的委托。 (我使用 lambda 来定义它们,这在提出问题时可能不可用,但如果有更多的代码,可以通过将它们定义为单独的函数来完成同样的事情。)
Func<Properties, Type> getType1 = properties => properties.GetType1();
Func<Properties, Type> getType2 = properties => properties.GetType2();
getType1(properties);
反思。
MethodInfo getType1 = properties.GetType().GetMethod("GetType1");
MethodInfo getType2 = properties.GetType().GetMethod("GetType2");
getType1.Invoke(properties, null);
表达式。它们类似于委托,只不过它们开辟了创建表达式或检查它们的替代方法(例如,确保它们是简单的方法调用)。 (这些在最初提出问题时可能不可用。)
Expression<Func<Properties, Type>> getType1 = properties => properties.GetType1();
Expression<Func<Properties, Type>> getType2 = properties => properties.GetType2();
getType1.Compile().Invoke(properties);
这是做不到的。
在 C++ 中,指向成员的指针非常有效,因为它使用对象结构中成员的偏移量。上述机制都没有完全模拟该方法或匹配该效率。委托(以及编译后的表达式)很接近,但它们将调用包装在另一个函数中,这意味着有两个函数调用,而在 C++ 中只有一个。
希望这是对原始问题的更完整的答案。