Reputation: 864
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...
Upvotes: 4
Views: 4125
Reputation: 158309
You have two issues in your code.
Delegate
object is not a method, so you need to use a method on the Delegate
object to invoke the method it refersCreateDelegate
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);
Upvotes: 3
Reputation: 24334
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
}
Upvotes: 1
Reputation: 234434
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.
Upvotes: 0
Reputation: 81660
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"});
Upvotes: 0
Reputation: 190945
You are using the Delegate
class not the delegate
keyword.
Upvotes: 0