Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass a type to a method - Type argument vs generics

I have a method of an object which is something like a factory. You give it a type, it creates an instance and does a few other things. An elegant way to do it (in my opinion) is like this:

public T MagicMethod<T>() where T: SomeBaseClass
{
    // Magic goes here
}

But this upsets FxCop who says that this is a bad style - I get a "CA1004: Generic methods should provide type parameter" warning. Something about not being to use inference and stuff. So, the only other way I can think of is something like this:

public SomeBaseClass MagicMethod(Type T)
{
    // Same magic goes here
}

I believe this is inferior to the first method on many accounts, but the style rule... The MSDN article on the warning even says that there is no reason for suppressing it.

Am I doing it right by suppressing this warning after all?

like image 663
Vilx- Avatar asked Jul 31 '09 12:07

Vilx-


2 Answers

I believe you're misunderstanding what FxCop is telling you, probably because its wording is less than ideal. What it means is that a generic method should provide a parameter that is of that type, not that a generic method should have a non-generic overload that provides a runtime Type instance. For example,

public void DoSomething<T>(T myParam);

The myParam is the sort of parameter it's referring to. The reason it wants this is, as you suggest, for inference. This allows you to do something like...

string foo = "bar";

DoSomething(foo);

instead of having to write

DoSomething<string>(foo);

In your case, it's fine to suppress the warning since you want the user to explicitly specify the type. I would suggest, however (assuming that your constructors are parameterless) that you change your where to where T : SomeBaseClass, new(). This means that it will direct the compiler to require that whatever type is passed in have a parameterless constructor. This also means that you can do new T() in your code.

like image 169
Adam Robinson Avatar answered Oct 18 '22 10:10

Adam Robinson


I would have no issue with suppressing this warning. For starters the equivalent in MS's own code is Activator.CreateInstance<T>()

public static T CreateInstance<T>()

It implies that the analysis rule should consider whether the return type of the method is covered by the generic parameter...

This has been mentioned in many places before:

  • CA1004 is not always appropriate
  • FxCop Microsoft.Design and Generic outputs

And there have been previous bugs in the rule for example:

public static void GenericMethod<T>(List<T> arg);

previously would trigger it (fixed in 2005 SP1).

I suggest filing a connect bug for your specific example

like image 36
ShuggyCoUk Avatar answered Oct 18 '22 10:10

ShuggyCoUk