I'm a newby to Stack Overflow so please go easy on me! I'm reading C# in Depth but I've come across a scenario that I don't believe is covered. A quick search of the web didn't throw up any results either.
Say I define the following overloaded methods:
void AreEqual<T>(T expected, T actual)
void AreEqual(object expected, object actual)
If I call AreEqual()
without specifying a type argument:
AreEqual("Hello", "Hello")
Is the generic or non-generic version of the method invoked? Is the generic method invoked with the type argument being inferred, or is the non-generic method invoked with the method arguments being implicitly cast to System.Object
?
I hope my question is clear. Thanks in advance for any advice.
Type inference represents the Java compiler's ability to look at a method invocation and its corresponding declaration to check and determine the type argument(s). The inference algorithm checks the types of the arguments and, if available, assigned type is returned.
Only reference types can be used as type arguments. A parameterized type such as List<int> or Set<short> is illegal. Only reference types can be used for instantiation of generic types and methods.
Type inference is the ability to automatically deduce, either partially or fully, the type of an expression at compile time. The compiler is often able to infer the type of a variable or the type signature of a function, without explicit type annotations having been given.
Generic Types Differ Based on Their Type Arguments: Consider the following Java code.
The generics can generate a function AreEqual(string, string)
. This is a closer match than AreEqual(object, object)
, so therefore the generic function is chosen.
Interestingly, the compiler will choose this generic function even if it results in a constraint violation error.
Look at this example:
using System.Diagnostics;
namespace ConsoleSandbox
{
interface IBar
{
}
class Program
{
static void Foo<T>(T obj1) where T: IBar
{
Trace.WriteLine("Inside Foo<T>");
}
static void Foo(object obj)
{
Trace.WriteLine("Inside Foo Object");
}
static void Main(string[] args)
{
Foo("Hello");
}
}
}
Even HERE it will choose the generic version over the non-generic version. And then you get this error:
The type 'string' cannot be used as type parameter 'T' in the generic type or method 'ConsoleSandbox.Program.Foo(T)'. There is no implicit reference conversion from 'string' to 'ConsoleSandbox.IBar'.
But if you add a function Foo(string obj1)
it will work.
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