4

My code is as follows:

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"); } 

It is giving me an error saying "error CS0118: 'del' is a 'variable' but is used like a 'method'"

What should I do to use this delegate? I want to call any of "get_chart_1" or "get_chart_2" function and both of them take a string input?

Thanks in advance...

5 Answers 5

3

You have two issues in your code.

  • A Delegate object is not a method, so you need to use a method on the Delegate object to invoke the method it refers
  • The first argument to CreateDelegate should be the delegate type, not the class containing a method you want to invoke.

Full working example:

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" } } 

In your case, the Main method should look like this:

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"); } 

Update
Note that CreateDelegate is case sensitive on the method name, unless you tell it not to.

// 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); 
Sign up to request clarification or add additional context in comments.

1 Comment

Got an exception: Error binding to target method :-(
1

The other answers have addressed the problem with your code, but I wanted to offer an alternative.

If there are a limited, finite number of methods that your retrieval class is choosing from, and they have the same signatures, this can be done much more efficiently without using reflection:

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"); } 

If there were a lot, you could just create an array instead of using a switch. Obviously you could just run the appropriate function directly from the switch, but I assume that the idea is you may want to pass the delegate back to the caller, and a construct like this lets you do that without using reflection, e.g.

public static Func<string,object> GetMethod { ... just return getChartMethod directly } 

1 Comment

yah...yours maybe a solution also if I am not forced to use delegate only.
0

You are using the Delegate class not the delegate keyword.

Comments

0

You cannot call a method on Delegate type. You have to use DynamicInvoke() which is very slowwwwwww.

Try this:

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

Comments

0

You can only call delegates with method call syntax, if they have a known signature. You need to cast your delegate to the delegate type you defined earlier.

var del = (PropertyRetrievalClass.getProperty)Delegate.CreateDelegate(typeof(PropertyRetrievalClass.getProperty), obj, "get_Chart_" + i.ToString()); 

You also need to change the first argument to CreateDelegate, because it should be the delegate type. And capitalize the "C" in "get_Chart_".

And then, you will need to cast the returned object to string:

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

Or change the delegate type and the methods to have string as their return type.

1 Comment

getProperty is not visible to Main. So Edited this way-> PropertyRetrievalClass.getProperty del = (PropertyRetrievalClass.getProperty) Delegate.CreateDelegate(typeof(PropertyRetrievalClass), obj, "get_chart_" + i.ToString() ); string output= new del("asldkl"); ************** It doesn't work either...I got this error-> The type or namespace name 'del' could not be found (are you missing a using directive or an assembly reference?)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.