Wrox Home  
Professional .NET 2.0 Generics
by Tod Golding
October 2005, Paperback

Type Inference

One really handy aspect of generic methods is their ability to examine the types of incoming arguments and infer which method should be invoked. This eliminates the need to explicitly specify type arguments when calling a generic method. Consider the following method declaration and corresponding calls:

[VB code]
Public Sub InferParams(Of I, J)(ByVal val1 As I, ByVal val2 As J)
Console.Out.WriteLine("I: {0}, J: {1}", val1.GetType(), val2.GetType())
End SubInferParams(Of Int32, String)(14, "Test")
InferParams("Param1", 3939.39)
InferParams(93, "Param2")
[C# code]
public void InferParams<I, J>(I val1, J val2) {
Console.Out.WriteLine("I: {0}, J: {1}", val1.GetType(), val2.GetType());
}InferParams<int, string>(14, "Test");
InferParams("Param1", 3939.39);
InferParams(93, "Param2");

This example declares a generic method that accepts two type parameters and provides three examples of calls to that method. The first call provides explicit type arguments. In this case, the types of the supplied parameter must match the types specified in the type parameter list. The next two examples both successfully call the InferParams() method without supplying any type arguments. They both use type inference, where the type is inferred from the types of the supplied arguments.

Leveraging this mechanism makes sense in most situations. However, in instances where you've overloaded a method, you may encounter some degree of ambiguity. Suppose you were to add the following overloaded method to the preceding example:

[VB code]
Public Sub InferParams(Of I, J)(ByVal val1 As Int32, ByVal val2 As String)
Console.Out.WriteLine("I: {0}, J: {1}", val1.GetType(), val2.GetType())
End Sub
[C# code]
public void InferParams<I, J>(int val1, string val2) {
Console.Out.WriteLine("I: {0}, J: {1}", val1.GetType(), val2.GetType());

This method overloads the previous InferParams() method, adding a version that includes specific integer and string types in its parameter list. Now, when you execute the sample calls to this method, it's not clear, from looking at the code, which method will get called. As it turns out, the example that supplied explicit type parameters would get you into this new method, and the version that infers the parameter types will get you into the other version of this method. Still, if you're overloading like this, it's probably not wise to rely on inference for your type parameters.

As you can see, generic methods are quite handy. They bring a whole new set of possibilities to how you approach your methods — especially those methods that may currently struggle with type-safety issues. And, thanks to type inference, consumers are often able to leverage generic methods without any direct awareness of any generic syntax. Authors of generic methods, on the other hand, do have some new factors to take into consideration when composing generic methods. Still, the handful of new rules that accompany generic methods are largely intuitive and most developers should be able to make the transition to generic methods with relative ease.

This article is adapted from Professional .NET 2.0 Generics by (Wrox, 2005, ISBN: 0-7645-5988-5), from chapter 5 "Generic Methods." Tod Golding has 20 years of experience as a software developer, lead architect, and development manager for organizations engaged in the delivery of large-scale commercial and internal solutions. He has an extensive background leveraging .NET, J2EE, and Windows DNA technologies, and is skilled with C#, Java, and C++. His other recent article on Wrox.com is a related article "Understanding Generic Classes" adapted from chapter 4 "Generic Clasess" in Professional .NET 2.0 Generics.