Using a generic type argument in place of an argument of type System.Type. Is it a smell?

c#, coding-style

Solution

I think you need to consider documentation. How obvious is it what the methods do? If you have two methods (one with `Type` and one with a type argument), users need to look at both and choose. People who aren't looking at your code may not realize that the second one simply calls the first.

Where it definitely makes sense to use both is when the type argument is actually used when it can be and there is some kind of fallback for the `Type` version. For example:

object GetThingOfType(Type type) { ... }

T GetThingOfType<T>() { return (T)GetThingOfType(typeof(T)); }

Another thing to consider: A type argument must always be written explicitly. If it is likely that there will be more than one operation to perform with the same type object, it's not helpful to use type arguments. Consider something like this:

var t = typeof(string);
var name = GetTypeName(t);
var assemblyName = t.Assembly.FullName;

Even though I know the type is `string`, I should not write `GetTypeName<string>` here because I would be repeating myself. By giving me an option that I would most often be better off not choosing, you're adding a bit of unnecessary complexity.

A more obscure point is IDE support of XML documentation. You document the type argument like this:

<typeparam name="T">important information</typeparam>

Then if you type `GetTypeName<` in C#, Visual Studio will show "T: important information". But, for some reason, when you type `GetTypeName(Of` in Visual Basic, it will not (as of 2012).

Problem

I often see (in many mocking libraries for example) methods where a generic type argument is used in place of an argument of type `System.Type`. I am specifically talking about cases where generic type is only being used in `typeof(T)` operation (i.e. no instance of type T is being used anywhere within the method, and T is not being used for either return type or other arguments). For example consider following method: ``` public string GetTypeName(System.Type type) { return type.FullName; } ``` this method is often accompanied with a generic version: ``` public string GetTypeName<T>() { return GetTypeName(typeof(T)); } ``` Questions is it a bad practice or a good practice? Is this a syntactic sugar or are there more to it? I see this as misusing a language feature to abbreviate a call to a method that accepts an argument of type `System.Type` Would you consider this a smell? Should this be avoided? or is this actually a good practice (to provide a generic method as a shortcut to avoid typing `typeof()`). Here are some practical issues with using this pattern I can think of: - if an argument of non System.Type type is added - method might need to be rewritten (if order of arguments is semantically significant) to non generic version (otherwise some arguments will be generic type arguments, and some will be regular arguments). - it requires two methods (generic and non generic for cases where type is not known at compile time). Consequently adds unit tests which are mostly meaningless. On the other hand this is a common practice (and majority is always right, right?) but more importantly ReSharper prefers that signature when I do Extract Method refactoring on a code that requires single argument of type System.Type known at compile time (and I learned to take their recommendations though not on faith, but seriously).

Original source

Related problems