在C#中委派错误

时间:2011-04-20 11:46:15

标签: 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)
    {
        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”函数中的任何一个,并且它们都接受字符串输入?

提前致谢...

5 个答案:

答案 0 :(得分:3)

您的代码中有两个问题。

  • 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);

答案 1 :(得分:1)

其他答案已经解决了您的代码问题,但我想提供一个替代方案。

如果检索类选择的方法数量有限且有限,并且它们具有相同的签名,则可以在不使用反射的情况下更有效地完成此操作:

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
}

答案 2 :(得分:0)

您无法在Delegate 类型上调用方法。你必须使用 very slowwwwwww DynamicInvoke()

试试这个:

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

答案 3 :(得分:0)

您使用的是Delegate课程而不是delegate关键字。

答案 4 :(得分:0)

如果代理具有已知签名,则只能使用方法调用语法调用委托。您需要将委托转换为您之前定义的委托类型。

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作为返回类型。