5

I have two generic delegates that I am atttempting to define that the compiler is complaining that they are duplicates, but to my eye are completely different. What am I doing/understanding wrong?

delegate TReturn foo<TParameter, out TReturn>(TParameter parameter, IItem item);

and

delegate TReturn foo<TParameter, out TReturn>(TParameter parameter, int field, IItem item);

If I add a new generic parameter to the second delegate, everything works.

delegate TReturn foo<TParameter, TField, out TReturn>(TParameter parameter, TField field, IItem item) where TField struct

but that is does not appear to be correct. I will always be passing an int for field - it should not be a generic.

Tim
  • 14,999
  • 1
  • 45
  • 68
David Williams
  • 823
  • 6
  • 16
  • What is the exact compile error? – Steven Jul 02 '12 at 15:50
  • The error is "The namespace 'xxx' already contains a definition for 'foo'". It kind of makes sense but I can't really explain it. – Rawling Jul 02 '12 at 15:58
  • 1
    i think you can simplify the question by removing the generics here. Lets say you have two delegates: `delegate void f()` and `delegate void f(int)`, and then you got a delegate object: `f a;`, you will have no idea which version of the delegate from which this object is instantiated. It's not safe to call either `a()` of `a(1)` because you don't know whether the delegate object actually represents a method with 0 or 1 argument. Therefore delegates are not like methods that can be overloaded – weidi Jul 02 '12 at 16:02

2 Answers2

6

Delegates are not methods. They know how to call a method, but they themselves are not methods (a delegate is an object) and can therefore not be overloaded like a method.

See this post for an explanation of why it cannot be possible.

Community
  • 1
  • 1
Kevin Aenmey
  • 13,259
  • 5
  • 46
  • 45
3

When using delegate keyword, what happens behind the scenes is that the compiler generates a class based on its definition. So when you define a delegate like this:

delegate TReturn foo<TParameter, out TReturn>(TParameter parameter, IItem item);

a following class is generated from it:

class foo<TParameter, out TReturn> : MulticastDelegate
{
    public void Invoke(TParameter parameter, IItem item) { ... }
    ....
}

As you can see, when you have two delegates with the same name and same generic parameters, it results in generation of two identical classes, which is, of course, not acceptable.

I recommend an excellent book CLR via C# from Jeffrey Richter that sheds more light on behind-the-scenes stuff like this - and much more.

watashiSHUN
  • 9,684
  • 4
  • 36
  • 44
Nikola Anusev
  • 6,940
  • 1
  • 30
  • 46