Gendarme.Rules.Design.Generic

Gendarme's rules about generic-related design issues are located in the Gendarme.Rules.Design.Generic.dll assembly. Latest sources are available from anonymous SVN (http://anonsvn.mono-project.com/viewcvs/trunk/mono-tools/gendarme/rules/Gendarme.Rules.Design.Generic/).

Rules

AvoidMethodWithUnusedGenericTypeRule

This rule checks for method that requires generic parameter types that are not used in the method parameters. This results in API that are hard to understand by consumers.

Bad example:

public class Bad {
    public string ToString<T> ()
    {
        return typeof (T).ToString ();
    }
    
    static void Main ()
    {
        Console.WriteLine (ToString<int> ());
    }
}

Good example:

public class Good {
    public string ToString<T> (T obj)
    {
        return obj.GetType ().ToString ();
    }
    
    static void Main ()
    {
        Console.WriteLine (ToString (2));
    }
}

Notes

  • This rule is available since Gendarme 2.2

DoNotExposeNestedGenericSignaturesRule

This rule checks for visible method parameters or return values that are exposing nested generic types. Such types are harder to construct and should not be imposed on the consumer of the API since simpler alternative generally exists. Since some language, like C#, have direct support for nullable types, i.e. Nullable<T> this specific case is ignored by the rule.

Bad example:

public class Generic<T> {
    public void Process (KeyValuePair<T, ICollection<int>> value)
    {
    }
}

Good example:

public class Generic<T> {
    public void Process (KeyValuePair<T, int[]> value)
    {
    }
}

Notes

  • This rule is available since Gendarme 2.4

ImplementGenericCollectionInterfacesRule

This rule checks for types that implements non-generic IEnumerable interface but does not implement IEnumerable<T> interface. Implementing the generic version of IEnumerable avoids casts, and possibly boxing, when iterating the collection.

Bad example:

public class IntEnumerable : IEnumerable {
    public IEnumerator GetEnumerator ()
    {
    }
}

Good example:

public class IntEnumerable : IEnumerable<int> {
    public IEnumerator<int> GetEnumerator ()
    {
    }
    
    IEnumerator IEnumerable.GetEnumerator ()
    {
    }
}

Notes

  • Before Gendarme 2.2 this rule was part of Gendarme.Rules.Design assembly.

PreferGenericsOverRefObjectRule

This rule looks at each parameter of every methods to find reference, ref or out in C#, to an System.Object. When using the CLR 2 (and later) such parameters can generally be rewritten using generics. This provides additional type safety, reduce casts and makes the API easier to consume.

Bad example:

// common before 2.0 but we can do better now
public bool TryGetValue (string key, ref object value)
{
    // ...
}

Good example:

public bool TryGetValue<T> (string key, ref T value)
{
    // ...
}

Notes

  • This rule is available since Gendarme 2.2

UseGenericEventHandlerRule

This rule checks for delegate definitions that are not required when using the 2.0 (or later) .NET framework as it can be replaced by using the generic-based System.EventHandler<TEventArgs>.

Bad example:

public delegate void AuthenticityHandler (object sender, AuthenticityEventArgs e);
 
public event AuthenticityHandler CheckingAuthenticity;
public event AuthenticityHandler CheckedAuthenticity;

Good example:

public event EventHandler<AuthenticityEventArgs> CheckingAuthenticity;
public event EventHandler<AuthenticityEventArgs> CheckedAuthenticity;

Notes

  • This rule is available since Gendarme 2.2

Feedback

Please report any documentation errors, typos or suggestions to the Gendarme Google Group (http://groups.google.com/group/gendarme). Thanks!