Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delegate - Method Name Expected Error

Tags:

c#

delegates

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.

like image 540
Dima Avatar asked Dec 04 '25 11:12

Dima


2 Answers

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.

like image 197
Jon Skeet Avatar answered Dec 08 '25 01:12

Jon Skeet


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);
}
like image 43
p.s.w.g Avatar answered Dec 08 '25 00:12

p.s.w.g



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!