Reputation: 51
I'm writing a console calculator on c#. I need the following code start working:
Dictionary<string, Delegate> functions = new Dictionary<string, Delegate>();
private void AddMyFunction (Delegate d, string name)
{
if (name == null)
{
name = d.Method.Name;
}
functions.Add (name, d);
}
public void AddFunction (Func<decimal, decimal> f, string name)
{
AddMyFunction (f, name);
}
public void AddFunction (Func<decimal, decimal, decimal> f, string name)
{
AddMyFunction (f, name);
}
public double PerformOperation (string op, decimal x)
{
return functions [ op ] (x);
}
In the function "PerformOperation" the error: "Method name expected" comes out. Please help someone.
Upvotes: 3
Views: 2374
Reputation: 149068
Change it to this:
public decimal PerformOperation (string op, decimal x)
{
return (decimal)(functions[op].DynamicInvoke(x));
}
And it will work. However, I'd recommend something a little more strongly typed. Perhaps keep multiple dictionaries, one for each delegate type, like this:
Dictionary<string, Func<decimal, decimal>> func1;
Dictionary<string, Func<decimal, decimal, decimal>> func2;
public void AddFunction (Func<decimal, decimal> f, string name)
{
func1.Add(name, f);
}
public void AddFunction (Func<decimal, decimal, decimal> f, string name)
{
func2.Add(name, f);
}
public decimal PerformOperation (string op, decimal x)
{
return func1[op](x);
}
public decimal PerformOperation (string op, decimal x, decimal y)
{
return func2[op](x, y);
}
Upvotes: 4
Reputation: 1503519
The problem is that you're trying to use the bare Delegate
type as if it were a specific delegate type. If you change your dictionary to:
Dictionary<string, Func<decimal, double>>
then that error goes away - but you won't be able to add a Func<decimal, decimal>
as a value in the dictionary, of course... or a Func<decimal, decimal, decimal>
.
You could use Delegate.DynamicInvoke
if you don't want to tie yourself to a specific delegate type - but then you'd still have a problem of handling the fact that you're expecting a double
return value but calling a delegate which returns a decimal
. You'll get an unboxing error if you just cast the result of DynamicInvoke
to double
.
There's also the problem that the delegate you're trying to call may have two parameters and you're only supplying one argument.
Basically you need to be more consistent about what you want the values in the dictionary to be.
Upvotes: 5