What is the Method Signature in the following
int DoSomething(int a, int b);
Return type is a part of signature or not???
Is the return type is a part of signature or not?
It depends on why you are asking the question. Why do you care?
There are two definitions of method signature. The C# language definition does not include the return type, and uses the signature of the method to determine whether two overloads are allowed. Two methods with the same signature are not allowed in a type. Since C# does not consider the return type to be a part of the signature, C# does not allow two methods that differ only in return type to be declared in the same type.
The CLR, however, does include the return type in the signature. The CLR allows for two methods to be in the same type that differ only in return type.
To be more specific: in C# the signature consists of the methods:
with the following additional notes:
In the CLR the signature consists of:
Note that the CLR does not distinguish between "ref int" and "out int" at all when considering signatures. Note that the CLR does distinguish between modopt/modreq types. (The way that the C# compiler deals with modopt/modreq types is too complex to summarize here.)
From MSDN:
The signature of a method consists of the name of the method and the type and kind (value, reference, or output) of each of its formal parameters, considered in the order left to right. The signature of a method specifically does not include the return type
Edit: That is from old documentation. It seems the definition of 'signature' has changed since then. Now a method has two different signatures, one for the purpose of overloading and one for the purposes of determining delegate compatibility. See keyboardP's answer below for more details.
From MSDN:
A return type of a method is not part of the signature of the method for the purposes of method overloading. However, it is part of the signature of the method when determining the compatibility between a delegate and the method that it points to.
To clarify, in your example the return type is not part of the signature. However, when you're matching the signature of a delegate, it is considered part of the signature. From MSDN:
Any method that matches the delegate's signature, which consists of the return type and parameters, can be assigned to the delegate. This makes is possible to programmatically change method calls, and also plug new code into existing classes. As long as you know the delegate's signature, you can assign your own delegated method.
So I believe it's based on context. Most of the time, and as shown in your code, the return type is not part of it. However, in the context of delegation, it is considered part of it.
DoSomething(int a, int b);
is the method signature,
int
is the return type.
take a look at this :Signatures and overloading
Return type is not part of the method signature in C#. Only the method name and its parameters types (but not the parameter names) are part of the signature. You cannot, for example, have these two methods:
int DoSomething(int a, int b);
string DoSomething(int a, int b);
To be clear: Methods cannot be overloaded based on their return type. They must have a unique name, unique parameter types, or pass their arguments differently (e.g. using out
or ref
).
Edit: To answer your original question, the method signature for your method is:
DoSomething(int, int)
Note that this all applies to normal methods. If you're talking about delegate
s, then you should see keyboardP's answer. (Short version: return type IS part of the signature for a delegate).
In the case when method have generic arguments understanding of signature becomes more confusing.
Generic types declaring on class level are considered as normal types.
But generic types declaring on method level are considered as index in method's generic arguments.
For example these all methods have different signatures.
class MyClass<TValue>
{
public void F(TValue v) { } // generics: 0, arg: TValue
public void F<X>(TValue v) { } // generics: 1, arg: TValue
public void F<X, Y>(TValue v) { } // generics: 2, arg: TValue
public void F<X>(X v) { } // generics: 1, arg: 0
public void F<X, Y>(X v) { } // generics: 2, arg: 0
public void F<X, Y>(Y v) { } // generics: 2, arg: 1
}