Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are implied generic type parameters

So, I ran across an answer by Servy ( https://stackoverflow.com/a/15098242/496680 ) and some of his code does this:

public static int BinarySearch<TSource, TKey>(...)

for an extension method, but he calls it like this:

arr.BinarySearch(...)

I asked around and somebody metioned that its an implied generic type parameter. I googled them but found no information on them. I understand how generics work but I'm failing to understand how/when to use these.

  1. Why does servy use them in his extention method?
  2. Is there a more official name for these that I can search for?
like image 929
Steve's a D Avatar asked Feb 26 '13 21:02

Steve's a D


People also ask

What is a generic type parameter?

Generic Methods A type parameter, also known as a type variable, is an identifier that specifies a generic type name. The type parameters can be used to declare the return type and act as placeholders for the types of the arguments passed to the generic method, which are known as actual type arguments.

How many type parameters can be used in a generic class?

Multiple parameters You can also use more than one type parameter in generics in Java, you just need to pass specify another type parameter in the angle brackets separated by comma.

What are type parameters in C#?

The type parameter is a placeholder for a specific type that the client specifies when they create an instance of the generic type. A generic class cannot be used as-is because it is simply a blueprint for that type.

What is infer generic type arguments?

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.


2 Answers

Well, you left out the most important part that makes it all work. The type parameters can be inferred by the actual object parameters passed in.

For instance:

static class Extensions {
  internal static IEnumerable<U> Test<T, U>(
                                   this IEnumerable<T> items,
                                   Func<T, U> converter) {
    foreach (T item in items) {
      yield return converter(item);
    }
  }
}

This extension method works on any IEnumerable class and will convert each item in the enumeration to another type based on the converter you provided. This is standard generics.

Now, there are many ways to call this method:

IEnumerable<int> values = Enumerable.Range<int>(1, 10);
Func<int, string> converter = i => i.ToString("0.00");

// Variation 1, explicit calling
IEnumerable<string> results1 = Extensions.Test<int, string>(values, converter);

// Variation 2, explicit calling with type inference
IEnumerable<string> results2 = Extensions.Test(values, converter);

// Variation 3, extension method calling, still providing explicit types
IEnumerable<string> results3 = values.Test<int, string>(converter);

// Variation 4, extension method with type inference
IEnumerable<string> results4 = values.Test(converter);

All four variations call the same method and return the same result. Type inference works by looking at the parameters passed and automatically inferring their types based on what's being provided. In our examples above, it's able to determine that type T is of type int because we passed in an IEnumerable<int> into the parameter for IEnumerable<T>. It is also able to infer that type U is of type string because we passed in a Func matching the initial type of T with int and returning a string. So the Func<T, U> is filled in with our converter function of Func<int, string>.

From the inference above, it's a standard generic method at that point. Type inference and extension methods are nothing more than convenience/syntactic sugar. In fact, if you decompile the output you can see that extension methods are replaced with static calls and are usually defined with the type parameters explicitly filled out. (This varies based on your decompiler and the set options).

like image 98
Joshua Avatar answered Oct 03 '22 02:10

Joshua


  1. He uses a generic method in this case because it allows his method to work with any type contained within a Collection<T>. The generic method makes this very flexible, and usable for any type. He uses the type inferrence when calling the method because it simplifies the code at the call site.

  2. The automatic handling is called Type Inferrence, and is covered, in detail, in the C# Language Specification, section 7.5.2: Type Inferrence. If you want to understand it in detail, I would recommend downloading the C# language specification.

like image 28
Reed Copsey Avatar answered Oct 03 '22 02:10

Reed Copsey