C# C语言中的委托错误#

C# C语言中的委托错误#,c#,C#,我的代码如下: 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) {

我的代码如下:

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");
        }
它给了我一个错误,说“error CS0118:‘del’是一个‘变量’,但像‘方法’一样使用”

我应该如何使用此委托?我想调用“get_chart_1”或“get_chart_2”函数中的任何一个,它们都接受字符串输入


提前感谢…

您不能在
委托
类型上调用方法。你必须使用
DynamicInvoke()
,这是非常慢的

试试这个:

string output = (string) del.DynamicInvoke(new object[]{"asldkl"});

您使用的是
Delegate
类,而不是
Delegate
关键字。

您只能使用方法调用语法调用具有已知签名的委托。您需要将委托强制转换为前面定义的委托类型

var del = (PropertyRetrievalClass.getProperty)Delegate.CreateDelegate(typeof(PropertyRetrievalClass.getProperty), obj, "get_Chart_" + i.ToString());
您还需要将第一个参数更改为
CreateDelegate
,因为它应该是委托类型。并在“get_Chart_”中大写“C”

然后,您需要将返回的
对象
强制转换为
字符串

string output= (string) del("asldkl");

或者更改委托类型和方法,使其返回类型为
string

代码中有两个问题

  • 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"
    }
}
更新
请注意,
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 int MethodIndex{get;set;}
公共静态void Main()
{
PropertyRetrievalClass obj=新的PropertyRetrievalClass();
Func-getchart方法;
开关(方法索引)
{
案例1:
getChartMethod=obj.get_chart_1;
打破
案例2:
getChartMethod=obj.get_chart_2;
打破
}            
字符串输出=getChartMethod(“asldkl”);
}
如果有很多,您可以创建一个数组而不是使用开关。显然,您可以直接从开关运行适当的函数,但我假设您可能希望将委托传递回调用方,这样的构造允许您在不使用反射的情况下执行该操作,例如

public static Func<string,object> GetMethod
{
 ... just return getChartMethod directly
}
公共静态函数GetMethod
{
…直接返回getChartMethod即可
}

getProperty对Main不可见。因此,以这种方式编辑->PropertyRetrievalClass.getProperty del=(PropertyRetrievalClass.getProperty)Delegate.CreateDelegate(typeof(PropertyRetrievalClass),obj,“get_chart_”+i.ToString();字符串输出=新的del(“asldkl”);****************它也不起作用…我得到了这个错误->类型或命名空间名称“del”找不到(你缺少一个using指令或程序集引用吗?)得到了一个异常:绑定到目标方法时出错:-(是的…如果我不被迫只使用委托,你的解决方案也可能是这样的。
public static Func<string,object> GetMethod
{
 ... just return getChartMethod directly
}