13

I am implementing a very simple rules engine that enforces some specifications dynamically at runtime.

The actual rules are stored in Tuples, and I have trouble storing a delegate to the string.EndsWith function.

The following code works for testing string equality, and returns False as expected ("A" is different from "B"):

var rule = new Tuple<string, Func<string, string, bool>, string>("A", string.Equals, "B");
Console.WriteLine(rule.Item2.Invoke(rule.Item1, rule.Item3));

However, I cannot figure out how to adapt this code to use the string.EndsWith function instead of string.Equals.

The following code does not compile and issues a Cannot convert from 'method group' to 'Func<string, string, bool>' error message in Visual Studio.

var rule = new Tuple<string, Func<string, string, bool>, string>("A", string.EndsWith, "B");
Console.WriteLine(rule.Item2.Invoke(rule.Item1, rule.Item3));

I did search before asking this question, but I cannot understand the answers provided in How do I fix 'compiler error - cannot convert from method group to System.Delegate'? or Cannot convert from method group to System.Func<string>. I do not see how to apply these to my problem.

Community
  • 1
  • 1
Laurent Vaylet
  • 377
  • 1
  • 2
  • 16
  • 2
    Just look at the signature of the method. None of them match the delegate, exactly as the error message is telling you. – Servy Feb 10 '16 at 16:51
  • Also let start from `string.EndsWith` - there is no such method, i.e. the following does not compile `bool test = string.EndsWith("ABC", "C");`, right? – Ivan Stoev Feb 10 '16 at 17:07
  • @Servy I thought the error message was telling me something different. But it makes sense now, you are right. – Laurent Vaylet Feb 10 '16 at 17:25
  • @IvanStoev You are perfectly right. I wrongly assumed the methods were following the same pattern. – Laurent Vaylet Feb 10 '16 at 17:26

1 Answers1

7

String.Equals and String.EndsWith have different method signatures and must be called differently.

Specifically, String.Equals is static and takes two strings and returns a bool. String.EndsWith is an instance method taking one string and returns a bool

You can resolve your issue by wrapping the String.EndsWith call in a lambda to change the signature to take two strings and return a bool:

var rule = new Tuple<string, Func<string, string, bool>, string>
    ("AB", (string a, string b) => a.EndsWith(b), "B");
Console.WriteLine(rule.Item2.Invoke(rule.Item1, rule.Item3));

In general, the error means that there is no way the compiler can interpret string.EndsWith as a Func<string, string, bool>. You may find this answer about what is a method group helpful to understanding the error message.

Community
  • 1
  • 1
Daniel
  • 12,982
  • 3
  • 36
  • 60