Is there a naming convention for type parameters on generic typed code?
I'm doing some TypeScript now but it has the same style of type parametrisation as C#, Java, AS3 etc.
I see most common used T
, als in:
interface Container<T> {
getContent(): List<T>;
}
But what if you need more then 1 type? I see single letters, usually T, U and V. Sometimes K, V are used for the key and value of mappings.
Surely there must be a best practice for this?
The official Sun/Oracle Java naming convention for generic type parameters is: By convention, type parameter names are single, uppercase letters.
Type Parameter Naming ConventionsE - Element (used extensively by the Java Collections Framework) K - Key. N - Number. T - Type.
Also, K is often used for a generic key type and V for a value type associated with it; in some cases E is used for the type of "elements" in a collection. Just to add - it's rare but occasionally you can use something more than letters for generic types.
Use the IsGenericType property to determine whether the type is generic, and use the IsGenericTypeDefinition property to determine whether the type is a generic type definition. Get an array that contains the generic type arguments, using the GetGenericArguments method.
A widely adopted standard is T1
, T2
, T3
, etc, if there is more than 1 unpurposed generic type parameter (that is, where the intended purpose of the parameters is not known from within the class itself, so you can't really give them a more descriptive name).
See Tuple
class, as a good example here.
Tuple
has the following forms:
Tuple<T1>
Tuple<T1, T2>
Tuple<T1, T2, T3>
Tuple<T1, T2, T3, T4>
Tuple<T1, T2, T3, T4, T5>
Tuple<T1, T2, T3, T4, T5, T6>
Tuple<T1, T2, T3, T4, T5, T6, T7>
Using anything else in cases like this will probably be confusing to anyone reading your code. On seeing T1
, T2
, T3
, everyone will know they are generic type parameters.
However, in the case of generic parameters with predefined purposes, specific names are more appropriate. As pointed out by @AlexeiLevenkov, for return values it's also very common to use TResult
to distinguish it from any other type arguments. Func
provides a good example of this, as described in the documentation here, with example below:
public delegate TResult Func<in T, out TResult>(
T arg
)
Along similar lines, Dictionary
uses <TKey, TValue>
as its type parameters. That's because it needs to be immediately clear which is which. The class code doesn't know what TKey
or TValue
are, but it does know they represent keys and values, so it make sense to put that information in the parameter name.
Microsoft have some (old!) naming guidelines here, where they cover another interesting case. They suggest indicating constraints placed on a type parameter in the name of the parameter itself, as follows:
public interface ISessionChannel<TSession> where TSession : ISession
{
TSession Session { get; }
}
In this case, because the generic parameter is constrained to be an ISession
, it makes sense to communicate this by naming the parameter TSession
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With