Return type as part of a method's signature
On the following page of the on-line documentation:
MSDN>MSDN Library>Development Tools and Languages>Visual Studio 2005>Visual Studio>.NET Framework Programming in Visual Studio>Overview of the .NET Framework>Common Type System>Type Members
(http://msdn2.microsoft.com/en-us/library/exe76ct6(VS.80).aspx)
on the first table shown on the page, in the row named method it says:
Method... A method's signature specifies the allowable types of all its arguments and of its return value.
I don't understand what it means here that the method signature specifies the type of the return value, in light of statements in the C# documentation:
Spec 1.2: Section: 1.6.5 Methods
The signature of a method consists of the name of the method and the number, modifiers, and types of its parameters. The signature of a method does not include the return type.ECMA Spec: Section 8.7.3 Methods
The signature of a method consists of the name of the method and the number,
modifiers, and types of its formal parameters, and the number of generic type parameters. The signature of a method does not include the return type...that say that the return type is not part of the method's signature.
Also later on in the same page in the section titled Overloading it says:
Method signatures consist of the method name and a parameter list (the order and types of the method's arguments).
and does not mention the type of the return value (which is consistent with my understading based on the above references).
Could someone explain to me what the first statement means that the method's signature specifies the type of the return value ?
Antworten
- Allowing method resolution based on the return type is allowed in the CLR because some languages support it and therefore as the CLR must support a superset of all language functionalities which it is to run, it also supports it. This would allow you to say, e.g.
string x = GetValue();
int x = GetValue();
...and have two different GetValue methods be called; one which returns a string and one which returns an int. As such the method signature in the CLR includes the return value as it is used for method selection.
C# on the other hand does not support method resolution based on the return type; this was a conscious decision by the language designers not to expose the feature of the CLR which allows it. There's no technical reason why they couldn't have done, they just felt it better not to. Because the return value is not used for method selection a C# method signature does not include it.
So both specifications are correct, they're just specifications of different things: the CLR and C#
Alle Antworten
- Allowing method resolution based on the return type is allowed in the CLR because some languages support it and therefore as the CLR must support a superset of all language functionalities which it is to run, it also supports it. This would allow you to say, e.g.
string x = GetValue();
int x = GetValue();
...and have two different GetValue methods be called; one which returns a string and one which returns an int. As such the method signature in the CLR includes the return value as it is used for method selection.
C# on the other hand does not support method resolution based on the return type; this was a conscious decision by the language designers not to expose the feature of the CLR which allows it. There's no technical reason why they couldn't have done, they just felt it better not to. Because the return value is not used for method selection a C# method signature does not include it.
So both specifications are correct, they're just specifications of different things: the CLR and C# - Yeah, the C# spec's description is more accurate. The return value type is indeed not considered when selecting one of several available overloads. The terms "signature" and "method declaration" are however often used interchangeably.
- It's not that the C# spec is more accurate - read my explanation above. They are two seperate spects for two different things. The first describes the CLR/CTS which does allow the return type to be part of the signature; the second describes C# which does not. C# is not the CLR/CTS, it is a language implementation that uses it.
- Okay Greg, you're right, please keep your pants on. I didn't see your post. Not sure what I did wrong when I said that the C# spec describes the C# language more accurately. Peace.
Thank you for your answer. I suspected such a thing but I wasn't sure about it, thank you for confirming it. Also the statement later on in the same page threw me off, it is talking at the CLR level, and says that the signature consists of the methond name, order and type of the arguments and does not mention the return type. I also couldn't understand the following:
If the overloading of methods is implemented in the CLR and the CLR overload logic is sensitive to the return type and the underlying development language being used is transparent to the CLR (meaning that the CLR doesn't know and doesn't care which language was used to generate the code), how can C# implement overloading which is not sensitive to the return type, how does C# use the CLR to do the actual overloading and at the same time get around the overloading functionality of the CLR.
But your answer implied that the underlying language has a certain amount of control over which features of the CLR to expose and which not, without understanding exaclty how this works the concept makes sense. Although the 2 statements on method signature on the same page still seem a little inconsistent to me.
Thank you again.
PS: also if you could tell me which languages support the retrun type as part of the method's signature ?
- The reason C# can support not using the return type as part of the method signature is because it is less specific than the CLR - for example (using C# syntax):
public string GetValue() { return "hello"; }
public int GetValue() { return 10; }
In the CLR it is valid to declare these because it recognises them as different, however in C# you will get a compiler error saying that methods cannot differ only on the basis of the return type. Therefore you have to remove any methods that only differ by return type, so the fact that the CLR would differentiate between them in this way doesn't matter as only one method exists that matches.
Not sure which languages do support this feature; I know there are some, but none that I've used. - I wasn't intending to be inflammatory just pointing out what the question was asking; my typical writing style is terse. Hope no offence caused, sorry.
Thank you, now it's clear. C# blocks this capability before it even gets to the CLR, so through the C# compiler the CLR never sees two methods that only differ in the return type.
Thank you for the explanation.
Now, without meaning to be picky, I still would like someone to address the inconsistency of the two statements on the page I referred to (both at the CLR level).
(http://msdn2.microsoft.com/en-us/library/exe76ct6(VS.80).aspx)
Well, either I found something that will settle this argument or I am throwing more wood into the fire. In my continued .NET training I found that both specifications are right even in C# itself. In the answer to the Lesson Review for Chapter 1 Lesson 3 of the MCTS 70-536 Exam Training Kit, Question 4, Answer A (the correct answer) I found the following statement A.Correct: Delegates define the signature (arguments and return type) for the entry point. The question being as follows (copied from the training kit):
You've implemented an event delegate from a class, but when you try to attach an event procedure you get a compiler error that there is no overload that matches the delegate. What happened?
The correct answer being:
A. The signature of the event procedure doesn't match that defined by the delegate
In the correct answer section quoted above (p945) I saw a hint of a place where even C# considers the return type as part of the signature of the mehtod and that is in event delegates/handler method matching. So I decide to check what it said on a real C# example and sure enough when it comes to delegate/handler method matching the return type is yes considered part of the method signature even for C#.
I tested it using the following example:
Code Snippetusing
System;namespace
CSTestDelegate{
public delegate bool MyEventHandler(object sender,EventArgs e); class Test{
public event MyEventHandler MyEvent; public void voidMyEvent(object sender, EventArgs e){
Console.WriteLine("voidMyEvent");}
public bool boolMyEvent(object sender, EventArgs e){
Console.WriteLine("boolMyEvent"); return true;}
public void RaiseMyEvent(){
if (MyEvent != null) MyEvent(this,EventArgs.Empty);}
}
class Program{
static void Main(string[] args){
Test t = new Test(); //t.MyEvent += new MyEventHandler(t.voidMyEvent);t.MyEvent +=
new MyEventHandler(t.boolMyEvent);t.RaiseMyEvent();
}
}
}
Sure enough if I uncomment the 2nd line in Main I get the following C# compiler error:
Error 1 'void CSTestDelegate.Test.voidMyEvent(object, System.EventArgs)' has the wrong return type C:\Documents and Settings\Administrator\Desktop\CSTestDelegate\CSTestDelegate\Program.cs 29 26 CSTestDelegate
I also verified what was said above that if two methods of a class only differ in the return type the C# compiler gives a error that there is already a method with the same name and parameter types (meaning with the same signature).
But there is a place (ie. event delegates) where the C# compiler does consider the return type as part of the signature. I assume that the same is true for Visual Basic although I didn't try it.
- The C# V1.2 Language Specification carefully avoids using the term "signature" when it talks about compatibility between a delegate type and a method in section 15.1:
A method and a delegate type are compatible if both of the following are true:
• They have the same number or parameters, with the same types, in the same order, with the same parameter modifiers.
• Their return types are the same. Yes. I noticed that also in the ECMA C# document that when it talks about delegate/method matching it uses the terms "consistent" and does not mention the word signature anywhere also the C# compiler errors themselves do not use the "signature" language but just point out the the return type does not match.
But it is not so for Visual Basic in both the spec and the compiler errors it describes the mismatch as a signature mismatch.
Although with regards to events Visual Basic does not allow to use delegates with return types but in using simple delegates it does and the errors are described in terms of signature.
Now, I am curious to see how delegate/method matching is described in the .NET documentation (besides the training kit for 70-536 mentioned above).
I saw an explanation for not considering the return type for overload resolution in Bjarne Stroustrup's book The C++ Programming Language, Special Edition, 15th printing, January 2007, Section 7.4.1 Overloading and Return Type. He explains that if the return type is taken into account in overload resolution, the resolution for and individual operator or function call would be context dependent, meaning it would depend on the context in which the call is made (as is show well by your example). Therefor he explains that in C++ the return type is not taken into account in order to keep operator/function resolution context independent, and he brings there his own example.
I don't think I fully undestood all of the implications of what he is saying, but I think that I got the jist of it. It could be that the other language design teams agreed with this and left the return type out of overload resolution for the same reason.

