c#中的委托错误
本文关键字:错误 | 更新日期: 2023-09-27 17:50:35
我的代码如下:
class PropertyRetrievalClass
{
public delegate object getProperty(string input);
public object get_Chart_1(string iput)
{
Console.WriteLine(iput);
return "";
}
public object get_Chart_2(string iput)
{
Console.WriteLine(iput);
return "";
}
public PropertyRetrievalClass() { }
}
public static void Main()
{
int i = 1;
PropertyRetrievalClass obj = new PropertyRetrievalClass();
Delegate del = Delegate.CreateDelegate(typeof(PropertyRetrievalClass), obj, "get_chart_" + i.ToString());
string output= del("asldkl");
}
它给了我一个错误说"错误CS0118: 'del'是一个'变量',但像'方法'一样使用"
我应该怎么使用这个委托?我想调用任何"get_chart_1"或"get_chart_2"函数,他们都采取字符串输入?
您的代码中有两个问题。
-
Delegate
对象不是一个方法,所以你需要在Delegate
对象上使用一个方法来调用它引用的方法
CreateDelegate
的第一个参数应该是委托类型,而不是包含你想调用的方法的类。完整的工作示例:
public delegate void ParamLess();
class SomeClass
{
public void PrintStuff()
{
Console.WriteLine("stuff");
}
}
internal class Program
{
private static Dictionary<int, int> dict = null;
static void Main()
{
var obj = new SomeClass();
Delegate del = Delegate.CreateDelegate(typeof(ParamLess), obj,
"PrintStuff", false);
del.DynamicInvoke(); // invokes SomeClass.PrintStuff, which prints "stuff"
}
}
在您的示例中,Main
方法应该如下所示:
public static void Main()
{
int i = 1;
PropertyRetrievalClass obj = new PropertyRetrievalClass();
Delegate del = Delegate.CreateDelegate(
typeof(PropertyRetrievalClass.getProperty),
obj,
"get_Chart_" + i.ToString());
string output = (string)del.DynamicInvoke("asldkl");
}
注意,CreateDelegate
对方法名是区分大小写的,除非您告诉它不要这样做。
// this call will fail, get_chart should be get_Chart
Delegate del = Delegate.CreateDelegate(
typeof(PropertyRetrievalClass.getProperty),
obj,
"get_chart_" + i.ToString());
// this call will succeed
Delegate del = Delegate.CreateDelegate(
typeof(PropertyRetrievalClass.getProperty),
obj,
"get_Chart_" + i.ToString());
// this call will succeed, since we tell CreateDelegate to ignore case
Delegate del = Delegate.CreateDelegate(
typeof(PropertyRetrievalClass.getProperty),
obj,
"get_chart_" + i.ToString(),
true);
其他答案已经解决了您的代码的问题,但我想提供另一种选择。
如果您的检索类选择的方法数量有限,并且它们具有相同的签名,则无需使用反射就可以更有效地完成:
public int MethodIndex {get;set;}
public static void Main()
{
PropertyRetrievalClass obj = new PropertyRetrievalClass();
Func<string,object> getChartMethod;
switch(MethodIndex)
{
case 1:
getChartMethod = obj.get_chart_1;
break;
case 2:
getChartMethod = obj.get_chart_2;
break;
}
string output= getChartMethod("asldkl");
}
如果有很多,你可以直接创建一个数组,而不是使用开关。显然,你可以直接从开关中运行适当的函数,但我认为你可能想要将委托传递回调用者,这样的构造可以让你在不使用反射的情况下做到这一点,例如
public static Func<string,object> GetMethod
{
... just return getChartMethod directly
}
您使用的是Delegate
类,而不是delegate
关键字。
不能在Delegate
类型上调用方法。你必须使用DynamicInvoke()
, 非常慢www。
试试这个:
string output = (string) del.DynamicInvoke(new object[]{"asldkl"});
您只能调用具有方法调用语法的委托,如果它们具有已知的签名。您需要将委托强制转换为先前定义的委托类型。
var del = (PropertyRetrievalClass.getProperty)Delegate.CreateDelegate(typeof(PropertyRetrievalClass.getProperty), obj, "get_Chart_" + i.ToString());
您还需要将第一个参数更改为CreateDelegate
,因为它应该是委托类型。并将"get_Chart_"中的"C"大写
然后,您需要将返回的object
转换为string
:
string output= (string) del("asldkl");
或者更改委托类型和方法,使其返回类型为string