UPDATE: It turns out that this was in fact a bug that has been corrected by Visual Studio 2005 Service Pack 1. Thanks to David Kean for the information. A full list of bugs in Managed Code Analysis bugs that are fixed by the service pack is available here.
In the comments section of my "Getting a little more graceful with generics" post from the other day, a reader brought this to my attention:
"When the line static void DoSomethingWithList... is changed to public static void DoSomethingWithList... and Code Analysis is run, it results in a CA1004 Microsoft.Design Warning 'GenericMethodsShouldProvideTypeParameter'"
In essence, when made visible to other types, the Code Analysis in Visual Studio Team System flags this method with a warning. Ugh! But, after examining the warning carefully, I'm not sure that the method is at fault. For reference, the documentation of this warning is on MSDN at http://msdn2.microsoft.com/en-us/library/ms182150.aspx.
In the documentation, the cause of this warning reads: "The parameter signature of an externally visible generic method does not contain types that correspond to all the type parameters of the method." In other words, this rule is in place to prevent code like this:
In the above declaration, there isn't a parameter (or return type) that uses the type parameter, T. To satisfy the rule, T has to be used as the type of a parameter or as the return type like this:
or:
In our case, we're using T in the method signature but not directly as a parameter type or the return type. Instead, we're using it to declare a generic type like this:
Is this in violation of the rule? Well, yes -- if you read the cause of the warning in a very strict sense. But, consider the rule description:
"Inference is how the type argument of a generic method is determined by the type of argument passed to the method, instead of by the explicit specification of the type argument. To enable inference, the parameter signature of a generic method must include a parameter that is of the same type as the type parameter for the method. In this case, the type argument does not have to be specified. When using inference for all type parameters, the syntax for calling generic and non-generic instance methods is identical. This simplifies the usability of generic methods."
For a moment, ignore the horrendous bit of wording used in the description ("how the type argument of a generic method is determined by the type of argument passed to the method") and recognize that the purpose of this rule is to enforce the fact that publicly visible generic methods should be declared in a way that allows them to be called using type inference. For those that are unclear on what type inference is as it relates to generic methods, check out my previous post.
So, this rule is in place to ensure that type inference works for public generic methods. However, the code that we're compiling clearly *does* allow type inference to work. Given this declaration:
I can call using type inference like this and it will compile fine:
The problem is that the rule doesn't consider the type arguments of any generic types in the method signature when verifying that all of the method's type parameters are used. However, it appears that the C# compiler does (so does the VB compiler). This smells like a bug to me. Comments? Opinions? Flames?
Page rendered at Wednesday, February 08, 2012 8:58:10 AM (Pacific Standard Time, UTC-08:00)
If feel a bit behind and need to catch up on WPF, this is the book.
Great book on F# containing from Beginner to Advanced. It even has chapters on more arcane features of the language, such as Computation Expressions and Quotations.
Because this book provides source code in Standard ML, it's a fantastic resource for learning F#. One bit of warning: this book does not teach classic data structures. While structures such as binomial heaps and red-black trees are presented, it is assumed that the reader already knows and understands them.
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.