✅ What is the syntax for generics in methods signature
Hello guys, consider the following:
TraverseBreadthFirst<T>(T, Func<T, IEnumerable<T>>)
Declaration:
public static IEnumerable<T> TraverseBreadthFirst<T>(T root, Func<T, IEnumerable<T>> childrenSelector)
Can someone explain what T refers to please, is it the return type or the type that the argument can take? I'm always confuse by that... what if we can have multiple generic parameters? How would we represent them?
Is there a syntax to follow? for example in the Func<T, IEnumerable<T>>
delegate type, I know that T
is the argument and IEnumerable<T>>
is the return type15 Replies
T is a type parameter, it can be either or both of the things you said
it basically lets you replace anywhere there's a T in the method with your own type when you call it
oh ok, irrespective whether it's a return type or argument, whatever we pass as our first argument, will represent the generic type ?
we can add more generic types by using something like
public static IEnumerable<T> TraverseBreadthFirst<T,X>(T root, X justAVariable , Func<T, IEnumerable<T>> childrenSelector)
?You can't dynamically change the type if that's what you mean
And yes, you can. Can't say what the limit is, though
you can have multiple type parameters like
<T1, T2, T3, ...>
The whole idea of a generic is so a common type can be used in a method without having to rely on that common type statically and instead you can just specify it yourself. Like here your collection
You can also specify a type that is not common, but does have a rule. For example, must not be null, or it must be a class/struct
(they also don't have to be called T, that's just convention)
the compiler just happens to be able to infer the type in some cases
One less important thing is also that it avoids boxing, if you care about that (or less important to most that is)
ero
REPL Result: Success
Compile: 326.853ms | Execution: 28.102ms | React with ❌ to remove this embed.
both
M(i)
and M<int>(i)
are valid here, because the compiler can infer that T
is int
in the first caseero
REPL Result: Failure
Exception: CompilationErrorException
Compile: 274.814ms | Execution: 0.000ms | React with ❌ to remove this embed.
this can never be valid, because the compiler can't know what
T
isoh ok, so in some cases, we can just write M(i) instead of M<int>(i) ?
yes, if the compiler can infer the type you don't need to specify it yourself
Alright noted, it's clearer now, thanks guys !!