In C#, generic type inference is the ability of the compiler to deduce the type arguments for a generic method or type, based on the context in which it's used. This means that you don't need to explicitly specify the type arguments, as the compiler can infer (deduce) them automatically. Let's take a look at an example:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
using
System;
namespace
HelloWorld
{
class
Program
{
static void Main(string[] args)
{
PrintValue<int>(2);
PrintValue<decimal>(2.3M);
Console.ReadLine();
}
static void PrintValue<T>(T param)
{
Console.WriteLine("The value is " + param);
}
}
}
|
You've seen this example before, in the lesson where I introduced you to generic types. What you didn't know is that we can rewrite this example like this:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
using
System;
namespace
HelloWorld
{
class
Program
{
static void Main(string[] args)
{
PrintValue(2);
PrintValue(2.3M);
Console.ReadLine();
}
static void PrintValue<T>(T param)
{
Console.WriteLine("The value is " + param);
}
}
}
|
The reason why I am allowed to call the PrintValue() method without specifying the types of the values that are being used as parameters to the generic method call is that the C# compiler can infer it from the values that were passed. Because in the first call, the method is called with the number 2, which is an int, the compiler can deduce that the T generic type becomes an int, so I don't need to tell it again, explicitly, by specifying it in the angle brackets. Same for the second call, if the value passed to the parameter was 2.3M, definitely that value is a decimal, no need to specify it again, like so PrintValue<decimal>(2.3M);. This is also the reason why the decimal part is of a darker color in Visual Studio, it lets us know that it is not required, the generic type parameter can be deduced.
In summary, generic type inference is a powerful feature of C#, that allows the compiler to automatically deduce the type arguments for a generic method or type, based on the context in which it's used. This can make your code more concise and easier to read, as you don't need to explicitly specify the types in all cases.
Be aware that type inference works by examining the types of the arguments passed to a generic method, in order to determine the type parameter of the method. This means that inference can only be used on generic methods, not generic classes. For instance, this will produce a compiler error:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
using
System;
namespace
HelloWorld
{
class
SomeClass<T>
{
public SomeClass(T param) { }
}
class
Program
{
static void Main(string[] args)
{
SomeClass someClass = new SomeClass(5);
Console.ReadLine();
}
}
}
|
In this case, I am still compelled to be specific: SomeClass<int> someClass = new SomeClass<int>(5), even if the compiler could look and see that I used number 5, and try to infer it from there.
It's also worth mentioning that the var keyword can be used in conjunction with type inference to create variables without explicitly specifying their type. When using the var keyword, the compiler will infer the type of the variable based on the type of the expression used to initialize it. Additionally, type inference does not always work with certain more complex types, such as arrays or anonymous types.