CA1000:DoNotDeclareStaticMembersOnGenericTypes - Reasonable Exception

Locked CA1000:DoNotDeclareStaticMembersOnGenericTypes - Reasonable Exception

  • Thursday, June 07, 2007 4:48 PM
     
     

    I created a static class (C#) which is used to safely convert an object to a value type. By safe I mean no exception will be thrown and the user can supply a default value to return if the conversion fails.

     

    This will obviously generate the CODE_ANALYSIS message CA1000Big SmileoNotDeclareStaticMembersOnGenericTypes.  The documentation for this message says it should never be excluded, what do you all think?

    Code Snippet

    public static class TryConvert<T>

    {

        /// <summary>

        /// Safely convert an object into an Int16 type.

        /// </summary>

        /// <param name="value">The object to convert.</param>

        /// <param name="defaultValue">The default value to return if conversion is not possible.</param>

        /// <returns>The converted value or the default value if conversion is not possible.</returns>

        public static short ToInt16(T value, short defaultValue)

        {

            short result;

            if (!short.TryParse(value.ToString(), out result))

                result = defaultValue;

     

            return result;

        }

    }

     

    // Usage

    public void SomeMethodSomewhere()

    {

        short result = TryConvert<string>.ToInt16("test", 1);

        Debug.Assert(result == 1);

    }

     

     

All Replies

  • Thursday, June 07, 2007 5:41 PM
    Moderator
     
     Answered

    There a couple of things:

     

    1) You're not actually getting a benefit by using generics in the above example, the same could be written using:

     

    Code Snippet

    public static class TryConvert

    {

        public static short ToInt16(object value, short defaultValue)

        {

            short result;

            if (!short.TryParse(value.ToString(), out result))

                result = defaultValue;


             return
    result;

        }

     

        public void Usage()

        {

            short result = TryConvert.ToInt16("test", 16);

        }

    }

     

    2) Given another example, you are better off placing the type parameter on the method itself as the compiler can infer the type parameter (where as it can't infer it if it is placed on the type):

     

    Code Snippet

    public static class StaticHolder

    {

        public static void Method<T>(T value)

        {

        }

     

        public static void Usage()

        {

            StaticHolder.Method("String"); // Do not need to specify type parameter

        }

    }

     

    If fact, 2) is exactly why the rule was written in the first place (see the docs for more information).

     

    Regards

     

    David

  • Thursday, June 07, 2007 7:01 PM
     
     

    Thanks David!

     

    Your second helps me understand the reason behind the rule. Why I didn't think of your first example is beyond me, I forgot to look for the simplest solution first!

     

     

  • Friday, July 06, 2012 7:16 PM
     
     

    Precisely because of the 2nd reason the rule should not exist or it should be safe to exclude.

    Consider an scenario where you have more than 1 generic type parameter, and you know that one of the parameters cannot be inferred, then it is a good idea to place that generic type parameter (the one that CANNOT be inferred) on the type and the ones that CAN be inferred on the method.

    If you do not do as I suggest and you place ALL generic parameters on the method then you wont be able to use type inference at all. Since one of them cannot be inferred then you need to specify all of them.

    Disclaimer: I know this is an old thread but hopefully someone at MS will read this and provide feedback ( specially if I am wrong :) ).