3.6 Signatures and Overloading
Methods, instance constructors, indexers, and operators are characterized by their signatures.
- 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; furthermore, it does not include the params modifier that may be specified for the rightmost parameter.
- The signature of an instance constructor consists of the type and kind (value, reference, or output) of each of its formal parameters, considered in the order left to right. The signature of an instance constructor specifically does not include the params modifier that may be specified for the rightmost parameter.
- The signature of an indexer consists of the type of each of its formal parameters, considered in the order left to right. The signature of an indexer specifically does not include the element type, nor does it include the params modifier that may be specified for the right-most parameter.
- The signature of an operator consists of the name of the operator and the type of each of its formal parameters, considered in the order left to right. The signature of an operator specifically does not include the result type.
Signatures are the enabling mechanism for overloading of members in classes, structs, and interfaces.
- Overloading of methods permits a class, struct, or interface to declare multiple methods with the same name, provided their signatures are unique within that class, struct, or interface.
- Overloading of instance constructors permits a class or struct to declare multiple instance constructors, provided their signatures are unique within that class or struct.
- Overloading of indexers permits a class, struct, or interface to declare multiple indexers, provided their signatures are unique within that class, struct, or interface.
- Overloading of operators permits a class or struct to declare multiple operators with the same name, provided their signatures are unique within that class or struct.
The following example shows a set of overloaded method declarations along with their signatures.
interface ITest
{ void F(); // F() void F(int x); // F(int) void F(ref int x); // F(ref int) void F(int x, int y); // F(int, int) int F(string s); // F(string) int F(int x); // F(int) error void F(string[] a); // F(string[]) void F(params string[] a); // F(string[]) error
}
Note that any ref and out parameter modifiers (§10.5.1) are part of a signature. Thus, F(int) and F(ref int) are unique signatures. Also, note that the return type and the params modifier are not part of a signature, so it is not possible to overload solely based on the return type or on the inclusion or exclusion of the params modifier. As such, the declarations of the methods F(int) and F(params string[]) identified in the previous example result in a compile-time error.