1693 строки
63 KiB
XML
1693 строки
63 KiB
XML
<?xml version="1.0"?>
|
|
<doc>
|
|
<assembly>
|
|
<name>Gendarme.Rules.Design</name>
|
|
</assembly>
|
|
<members>
|
|
<member name="T:Gendarme.Rules.Design.AbstractTypesShouldNotHavePublicConstructorsRule">
|
|
<summary>
|
|
This rule fires if an <c>abstract</c> type has a <c>public</c> constructor. This is
|
|
a bit misleading because the constructor can only be called by the constructor of
|
|
a derived type. To make the type's semantics clearer make the constructor
|
|
<c>protected</c>.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
abstract public class MyClass {
|
|
public MyClass ()
|
|
{
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
abstract public class MyClass {
|
|
protected MyClass ()
|
|
{
|
|
}
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.AttributeArgumentsShouldHaveAccessorsRule">
|
|
<summary>
|
|
This rule fires if a parameter to an <c>Attribute</c> constructor is not exposed
|
|
using a properly cased property. This is a problem because it is generally not useful
|
|
to set state within an attribute without providing a way to get at that state.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
[AttributeUsage (AttributeTargets.All)]
|
|
public sealed class AttributeWithRequiredProperties : Attribute {
|
|
private int storedFoo;
|
|
private string storedBar;
|
|
// we have no corresponding property with the name 'Bar' so the rule will fail
|
|
public AttributeWithRequiredProperties (int foo, string bar)
|
|
{
|
|
storedFoo = foo;
|
|
storedBar = bar;
|
|
}
|
|
public int Foo {
|
|
get {
|
|
return storedFoo;
|
|
}
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
[AttributeUsage (AttributeTargets.All)]
|
|
public sealed class AttributeWithRequiredProperties : Attribute {
|
|
private int storedFoo;
|
|
private string storedBar;
|
|
public AttributeWithRequiredProperties (int foo, string bar)
|
|
{
|
|
storedFoo = foo;
|
|
storedBar = bar;
|
|
}
|
|
public int Foo {
|
|
get {
|
|
return storedFoo;
|
|
}
|
|
}
|
|
public string Bar {
|
|
get {
|
|
return storedBar;
|
|
}
|
|
}
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.AvoidEmptyInterfaceRule">
|
|
<summary>
|
|
This rule fires if an interface declares no members. Empty interfaces are generally
|
|
not useful except as markers to categorize types and attributes are the preferred
|
|
way to handle that.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
public interface IMarker {
|
|
}
|
|
public class MyClass : IMarker {
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
[MarkedByAnAttribute]
|
|
public class MyClass {
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.AvoidMultidimensionalIndexerRule">
|
|
<summary>
|
|
This rule checks for externally visible indexer properties which have more
|
|
than one index argument. These can be confusing to some developers and
|
|
IDEs with auto-complete don't always handle them as well as methods so
|
|
it can be hard to know which argument is which.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
public int this [int x, int y] {
|
|
get {
|
|
return 0;
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
public int Get (int x, int y)
|
|
{
|
|
return 0;
|
|
}
|
|
</code></example>
|
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.AvoidPropertiesWithoutGetAccessorRule">
|
|
<summary>
|
|
This rule fires if an externally visible type contains a property with a setter but
|
|
not a getter. This is confusing to users and can make it difficult to use shared
|
|
objects. Instead either add a getter or make the property a method.
|
|
</summary>
|
|
<example>
|
|
Bad examples:
|
|
<code>
|
|
public double Seed {
|
|
// no get since there's no use case for it
|
|
set {
|
|
seed = value;
|
|
}
|
|
}
|
|
public sting Password {
|
|
// no get as we don't want to expose the password
|
|
set {
|
|
password = value;
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good examples:
|
|
<code>
|
|
public double Seed {
|
|
get {
|
|
return seed;
|
|
}
|
|
set {
|
|
seed = value;
|
|
}
|
|
}
|
|
public void SetPassword (string value)
|
|
{
|
|
password = value;
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.AvoidVisibleFieldsRule">
|
|
<summary>
|
|
This rule fires if a type contains externally visible fields. Instead use
|
|
a property which allows you to change the implementation without breaking
|
|
binary compatibility with other assemblies.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
public class Foo {
|
|
public int Value;
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
public class Foo {
|
|
private int v;
|
|
public int Value {
|
|
get {
|
|
return v;
|
|
}
|
|
set {
|
|
v = value;
|
|
}
|
|
}
|
|
</code></example>
|
|
<remarks>Prior to Gendarme 2.2 this rule was named AvoidPublicInstanceFieldsRule.</remarks>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.AvoidRefAndOutParametersRule">
|
|
<summary>
|
|
This rule fires if a method uses <c>ref</c> or <c>out</c> parameters.
|
|
These are advanced features that can easily be misunderstood and misused
|
|
(by the consumer). This can result in an API that is difficult to use so
|
|
avoid them whenever possible.
|
|
An alternative is to use one of the new generic <c>Tuple</c> types (FX v4 and later)
|
|
as the return value.
|
|
No defect will be reported if the method:
|
|
<list><item>follows the <c>bool Try*(X out)</c> pattern; or</item><item>implement an interface requiring the use of <c>ref</c> or <c>out</c> parameters.
|
|
In the later case defects will be reported against the interface itself (if analyzed
|
|
by Gendarme).</item></list></summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
public bool NextJob (ref int id, out string display)
|
|
{
|
|
if (id < 0)
|
|
return false;
|
|
display = String.Format ("Job #{0}", id++);
|
|
return true;
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
private int id = 0;
|
|
private int GetNextId ()
|
|
{
|
|
int id = this.id++;
|
|
return id;
|
|
}
|
|
public string NextJob ()
|
|
{
|
|
return String.Format ("Job #{0}", Id);
|
|
}
|
|
</code></example>
|
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.AvoidSmallNamespaceRule">
|
|
<summary>
|
|
This rule fires if a namespace contains less than five (by default) visible types. Note
|
|
that this rule enumerates the types in all the assemblies being analyzed instead of
|
|
simply considering each assembly in turn.
|
|
The rule exempts:
|
|
<list><item><term>specialized namespaces</term><description>e.g. <c>*.Design</c>,
|
|
<c>*.Interop</c> and <c>*.Permissions</c></description></item><item><term>internal namespaces</term><description>namespaces without any visible
|
|
(outside the assemble) types</description></item><item><term>small assemblies</term><description>that contains a single namespace but less than
|
|
the minimal number of types (e.g. addins)</description></item><item><term>assembly entry point</term><description>the namespace of the type being
|
|
used in an assemble (EXE) entry-point</description></item></list></summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
namespace MyStuff.Special {
|
|
// single type inside a namespace
|
|
public class Helper {
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
namespace MyStuff {
|
|
public class Helper {
|
|
}
|
|
// ... many other types ...
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="P:Gendarme.Rules.Design.AvoidSmallNamespaceRule.Minimum">
|
|
<summary>
|
|
The minimum number of types which must exist within a namespace.
|
|
</summary>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.AvoidVisibleNestedTypesRule">
|
|
<summary>
|
|
This rule checks for nested types which are externally visible. Such types are often
|
|
confused with namespaces which makes them more difficult to document and find by
|
|
developers. In most cases it is better to make these types private or to scope them
|
|
within a namespace instead of a type.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
public class Outer {
|
|
public class Inner {
|
|
// ...
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example (visibility):
|
|
<code>
|
|
public class Outer {
|
|
internal class Inner {
|
|
// ...
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example (unnested):
|
|
<code>
|
|
public class Outer {
|
|
// ...
|
|
}
|
|
public class Inner {
|
|
// ...
|
|
}
|
|
</code></example>
|
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.ConsiderAddingInterfaceRule">
|
|
<summary>
|
|
This rule fires if a type implements members which are declared in an
|
|
interface, but the type does not implement the interface. Implementing
|
|
the interface will normally make the type more reuseable and will help
|
|
clarify the type's semantics.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
public interface IDoable {
|
|
public void Do ();
|
|
}
|
|
public class MyClass {
|
|
public void Do ()
|
|
{
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
public interface IDoable {
|
|
public void Do ();
|
|
}
|
|
public class MyClass : IDoable {
|
|
public void Do ()
|
|
{
|
|
}
|
|
}
|
|
</code></example>
|
|
<remarks>Types and methods with generic constraints are presently ignored by the rule.</remarks>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.ConsiderConvertingFieldToNullableRule">
|
|
<summary>
|
|
This rule checks for pairs of fields which seem to provide the same
|
|
functionality as a single nullable field. If the assembly targets version 2.0,
|
|
or more recent, of the CLR then the rule will fire to let you know that a
|
|
nullable field can be used instead. The rule will ignore assemblies targeting
|
|
earlier versions of the CLR.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
public class Bad {
|
|
bool hasFoo;
|
|
int foo;
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
public class Good {
|
|
int? foo;
|
|
}
|
|
</code></example>
|
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.ConsiderConvertingMethodToPropertyRule">
|
|
<summary>
|
|
This rule checks for methods whose definition looks similar to a property.
|
|
For example, methods beginning with <c>Is</c>, <c>Get</c> or <c>Set</c> may
|
|
be better off as properties. But note that this should not be done if the method
|
|
takes a non-trivial amount of time to execute.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
public class Bad {
|
|
int foo;
|
|
public int GetFoo ()
|
|
{
|
|
return foo;
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
public class Good {
|
|
int foo;
|
|
public int Foo {
|
|
get {
|
|
return foo;
|
|
}
|
|
}
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.ConsiderUsingStaticTypeRule">
|
|
<summary>
|
|
This rule checks for types that contain only static members and, if the assembly
|
|
targets the CLR version 2.0 or later, suggests that the type be made <c>static</c>
|
|
or, for earlier versions, that the type be made <c>sealed</c>.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
public class Class {
|
|
public static void Method ()
|
|
{
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example (targetting CLR 2.0 and later):
|
|
<code>
|
|
public static class Class {
|
|
public static void Method ()
|
|
{
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example (targetting CLR 1.x):
|
|
<code>
|
|
public sealed class Class {
|
|
public static void Method ()
|
|
{
|
|
}
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.DeclareEventHandlersCorrectlyRule">
|
|
<summary>
|
|
This rule will fire if an event is declared with a signature which does not match
|
|
the .NET guidelines. The return type of the event should be void (because there
|
|
is no good way to handle return values if multiple delegates are attached to the
|
|
event). And the event should take two arguments. The first should be of type
|
|
<c>System.Object</c> and be named 'sender'. The second should be of type
|
|
<c>System.EventArgs</c> (or a subclass) and named 'e'. This helps tools
|
|
such as visual designers identify the delegates and methods which may be
|
|
attached to events. Note that .NET 2.0 added a generic <c>System.EventHandler</c>
|
|
type which can be used to easily create events with the correct signature.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
// the second parameter (which should be System.EventArgs or a derived class) is missing
|
|
delegate void MyDelegate (int sender);
|
|
class Bad {
|
|
public event MyDelegate CustomEvent;
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example (delegate):
|
|
<code>
|
|
delegate void MyDelegate (int sender, EventArgs e);
|
|
class Good {
|
|
public event MyDelegate CustomEvent;
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example (generics):
|
|
<code>
|
|
class Good {
|
|
public event EventHandler<EventArgs> CustomEvent;
|
|
}
|
|
</code></example>
|
|
<remarks>This rule is available since Gendarme 2.2</remarks>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.DisposableTypesShouldHaveFinalizerRule">
|
|
<summary>
|
|
This rule will fire for types which implement <c>System.IDisposable</c>, contain
|
|
native fields such as <c>System.IntPtr</c>, <c>System.UIntPtr</c>, and
|
|
<c>System.Runtime.InteropServices.HandleRef</c>, but do not define a finalizer.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
class NoFinalizer {
|
|
IntPtr field;
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
class HasFinalizer {
|
|
IntPtr field;
|
|
~HasFinalizer ()
|
|
{
|
|
UnmanagedFree (field);
|
|
}
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.DoNotDeclareSettersOnCollectionPropertiesRule">
|
|
<summary>
|
|
The rule detect <c>System.Collections.ICollection</c> and
|
|
<c>System.Collections.Generic.ICollection<T></c> properties that declare a visible setter.
|
|
There is rarely a need to be able to replace the collection (e.g. most collections provide a <c>Clear</c>
|
|
method) and having a getter only does not prevent the consumer from adding and removing items in the collection.
|
|
Also read-only properties have special support for binary and XML serialization, making your code more useful.
|
|
A special exception is made for <c>System.Security.PermissionSet</c> and types that derives from it.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
public class Holder {
|
|
public string Name { get; set; }
|
|
public ICollection<string> List { get; set; }
|
|
}
|
|
public static Holder Copy (Holder h)
|
|
{
|
|
Holder copy = new Holder ();
|
|
copy.Name = h.Name;
|
|
// bad, same list would be shared between instances
|
|
copy.List = h.List;
|
|
copy.List.AddRange (h.List);
|
|
return copy;
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
public class Holder {
|
|
List<string> list;
|
|
public Holder ()
|
|
{
|
|
list = new List<string> ();
|
|
}
|
|
public string Name { get; set; }
|
|
public ICollection<string> List {
|
|
get { return list; }
|
|
}
|
|
}
|
|
public static Holder Copy (Holder h)
|
|
{
|
|
Holder copy = new Holder ();
|
|
copy.Name = h.Name;
|
|
copy.List.AddRange (h.List);
|
|
return copy;
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.DoNotDeclareVirtualMethodsInSealedTypeRule">
|
|
<summary>
|
|
This rule ensure that <c>sealed</c> types (i.e. types that you can't inherit from)
|
|
do not define new <c>virtual</c> methods. Such methods would only be useful in
|
|
sub-types. Note that some compilers, like C# and VB.NET compilers, do not allow you
|
|
to define such methods.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
public sealed class MyClass {
|
|
// note that C# compilers won't allow this to compile
|
|
public virtual int GetAnswer ()
|
|
{
|
|
return 42;
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
public sealed class MyClass {
|
|
public int GetAnswer ()
|
|
{
|
|
return 42;
|
|
}
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.DoNotDeclareProtectedMembersInSealedTypeRule">
|
|
<summary>
|
|
This rule ensures that <c>sealed</c> types (i.e. types that you can't inherit from)
|
|
do not define family (<c>protected</c> in C#) fields or methods. Instead make the
|
|
member private so that its accessibility is not misleading.
|
|
</summary>
|
|
<example>
|
|
Bad example (field):
|
|
<code>
|
|
public sealed class MyClass {
|
|
protected int someValue;
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Bad example (method):
|
|
<code>
|
|
public sealed class MyClass {
|
|
protected int GetAnswer ()
|
|
{
|
|
return 42;
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example (field):
|
|
<code>
|
|
public sealed class MyClass {
|
|
private int someValue;
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example (method):
|
|
<code>
|
|
public sealed class MyClass {
|
|
private int GetAnswer ()
|
|
{
|
|
return 42;
|
|
}
|
|
}
|
|
</code></example>
|
|
<remarks>Prior to Gendarme 2.2 this rule applied only to fields and was named DoNotDeclareProtectedFieldsInSealedClassRule</remarks>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.EnsureSymmetryForOverloadedOperatorsRule">
|
|
<summary>
|
|
This rule checks for operators that are not overloaded in pairs. Some compilers, like
|
|
the C# compilers, require you to implement some of the pairs, but other languages might
|
|
not. The following pairs are checked:
|
|
<list><description>Addition and Substraction</description><description>Multiplication and Division</description><description>Division and Modulus</description><description>Equality and Inequality</description><description>True and False</description><description>GreaterThan and LessThan</description><description>GreaterThanOrEqual and LessThanOrEqual</description></list></summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
class DoesNotOverloadAdd {
|
|
public static int operator - (DoesNotOverloadAdd left, DoesNotOverloadAdd right)
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
class Good {
|
|
public static int operator + (Good right, Good left)
|
|
{
|
|
return 0;
|
|
}
|
|
public static int operator - (Good right, Good left)
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.EnumeratorsShouldBeStronglyTypedRule">
|
|
<summary>
|
|
This rule checks that types which implements <c>System.Collections.IEnumerator</c> interface
|
|
have strongly typed version of the IEnumerator.Current property.
|
|
This is needed to avoid casting every time this property is used.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
class Bad : IEnumerator {
|
|
object Current
|
|
{
|
|
get { return current; }
|
|
}
|
|
// other IEnumerator members
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
class Good : IEnumerator {
|
|
object IEnumerator.Current
|
|
{
|
|
get { return current; }
|
|
}
|
|
public Exception Current
|
|
{
|
|
get { return (Exception)current; }
|
|
}
|
|
// other IEnumerator members
|
|
}
|
|
</code></example>
|
|
<remarks>
|
|
Types inheriting from <c>System.Collections.CollectionBase</c>, <c>System.Collections.DictionaryBase</c>
|
|
or <c>System.Collections.ReadOnlyCollectionBase</c> are exceptions to this rule.</remarks>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.EnumsShouldDefineAZeroValueRule">
|
|
<summary>
|
|
This rule ensures that every non-flags enumeration contains a <c>0</c>
|
|
value. This is important because if a field is not explicitly initialized .NET
|
|
will zero-initialize it and, if the enum has no zero value, then it will be
|
|
initialized to an invalid value.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
enum Position {
|
|
First = 1,
|
|
Second
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
enum Position {
|
|
First,
|
|
Second
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.EnumsShouldUseInt32Rule">
|
|
<summary>
|
|
Enumaration types should avoid specifying a non-default storage type for their values
|
|
unless it is required for interoperability (e.g. with native code). If you do use a non-default
|
|
type for the enum, and the enum is externally visible, then prefer the CLS-compliant
|
|
integral types: System.Byte, System.Int16, System.Int32, and System.Int64.
|
|
</summary>
|
|
<example>
|
|
Bad examples:
|
|
<code>
|
|
public enum SmallEnum : byte {
|
|
Zero,
|
|
One
|
|
}
|
|
[Flags]
|
|
public enum SmallFlag : ushort {
|
|
One = 1,
|
|
// ...
|
|
Sixteen = 1 << 15
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
public enum SmallEnum {
|
|
Zero,
|
|
One
|
|
}
|
|
[Flags]
|
|
public enum SmallFlag {
|
|
One = 1,
|
|
// ...
|
|
Sixteen = 1 << 15
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.FinalizersShouldBeProtectedRule">
|
|
<summary>
|
|
This rule verifies that finalizers are only visible to the type's family (e.g. protected in C#).
|
|
If they are not family then they can be called from user code which could lead to
|
|
problems. Note that this restriction is enforced by the C# and VB.NET compilers
|
|
but other compilers may not do so.
|
|
</summary>
|
|
<example>
|
|
Bad example (IL):
|
|
<code>
|
|
.class family auto ansi beforefieldinit BadPublicFinalizer extends
|
|
[mscorlib]System.Object
|
|
{
|
|
.method public hidebysig instance void Finalize() cil managed
|
|
{
|
|
// ...
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example (C#):
|
|
<code>
|
|
public class GoodProtectedFinalizer {
|
|
// compiler makes it protected
|
|
~GoodProtectedFinalizer ()
|
|
{
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example (IL):
|
|
<code>
|
|
.class family auto ansi beforefieldinit GoodProtectedFinalizer extends
|
|
[mscorlib]System.Object
|
|
{
|
|
.method family hidebysig instance void Finalize() cil managed
|
|
{
|
|
// ...
|
|
}
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.FlagsShouldNotDefineAZeroValueRule">
|
|
<summary>
|
|
This rule ensures that enumerations decorated with the [System.Flags]
|
|
attribute do not contain a 0 value. This value would not be usable
|
|
with bitwise operators.
|
|
</summary>
|
|
<example>
|
|
Bad example (using 0 for a normal value):
|
|
<code>
|
|
[Flags]
|
|
[Serializable]
|
|
enum Access {
|
|
Read = 0,
|
|
Write = 1
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Bad example (using None):
|
|
<code>
|
|
[Flags]
|
|
[Serializable]
|
|
enum Access {
|
|
// this is less severe since the name of the 0 value helps
|
|
None = 0,
|
|
Read = 1,
|
|
Write = 2
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
[Flags]
|
|
[Serializable]
|
|
enum Access {
|
|
Read = 1,
|
|
Write = 2
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.ImplementEqualsAndGetHashCodeInPairRule">
|
|
<summary>
|
|
This rule checks for types that either override the <c>Equals(object)</c> method
|
|
without overriding <c>GetHashCode()</c> or override <c>GetHashCode</c> without
|
|
overriding <c>Equals</c>. In order to work correctly types should always override
|
|
these together.
|
|
</summary>
|
|
<example>
|
|
Bad example (missing GetHashCode):
|
|
<code>
|
|
public class MissingGetHashCode {
|
|
public override bool Equals (object obj)
|
|
{
|
|
return this == obj;
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Bad example (missing Equals):
|
|
<code>
|
|
public class MissingEquals {
|
|
public override int GetHashCode ()
|
|
{
|
|
return 42;
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
public class Good {
|
|
public override bool Equals (object obj)
|
|
{
|
|
return this == obj;
|
|
}
|
|
public override int GetHashCode ()
|
|
{
|
|
return 42;
|
|
}
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.ImplementIComparableCorrectlyRule">
|
|
<summary>
|
|
This rule checks for types that implement <c>System.IComparable</c> and verifies
|
|
that the type overrides the <c>Equals(object)</c> method and overloads the <c>==</c>,
|
|
<c>!=</c>, <c><</c> and <c>></c> operators.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
public struct Comparable : IComparable {
|
|
private int x;
|
|
public int CompareTo (object obj)
|
|
{
|
|
return x.CompareTo (((Comparable)obj).x);
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
public struct Comparable : IComparable {
|
|
public int CompareTo (object obj)
|
|
{
|
|
return x.CompareTo (((Comparable)obj).x);
|
|
}
|
|
public override bool Equals (object obj)
|
|
{
|
|
return x == ((Comparable) obj).x;
|
|
}
|
|
static public bool operator == (Comparable left, Comparable right)
|
|
{
|
|
return (left.x == right.x);
|
|
}
|
|
static public bool operator != (Comparable left, Comparable right)
|
|
{
|
|
return (left.x != right.x);
|
|
}
|
|
static public bool operator > (Comparable left, Comparable right)
|
|
{
|
|
return (left.x > right.x);
|
|
}
|
|
static public bool operator < (Comparable left, Comparable right)
|
|
{
|
|
return (left.x < right.x);
|
|
}
|
|
}
|
|
</code></example>
|
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.InternalNamespacesShouldNotExposeTypesRule">
|
|
<summary>
|
|
This rule checks for externally visible types that reside inside internal namespaces, i.e.
|
|
namespaces ending with <c>Internal</c> or <c>Impl</c>.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
namespace MyStuff.Internal {
|
|
public class Helper {
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example (internal type):
|
|
<code>
|
|
namespace MyStuff.Internal {
|
|
internal class Helper {
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example (non-internal namespace):
|
|
<code>
|
|
namespace MyStuff {
|
|
public class Helper {
|
|
}
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.ListsAreStronglyTypedRule">
|
|
<summary>
|
|
This rule checks that types which implements <c>System.Collections.IList</c> interface
|
|
have strongly typed versions of IList.Item, IList.Add, IList.Contains, IList.IndexOf, IList.Insert and IList.Remove.
|
|
This is needed to avoid casting every time these members are used.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
class Bad : IList {
|
|
public int Add (object value)
|
|
{
|
|
// method code
|
|
}
|
|
// other IList methods and properties without their strongly typed versions
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
class Good : Ilist {
|
|
public int Add (object value)
|
|
{
|
|
// method code
|
|
}
|
|
public int Add (Exception value)
|
|
{
|
|
return ((IList)this).Add ((object)value);
|
|
}
|
|
// other IList methods and properties with their strongly typed versions
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.MainShouldNotBePublicRule">
|
|
<summary>
|
|
This rule fires if an assembly's entry point (typically named <c>Main</c>) is visible
|
|
to other assemblies. It is better to make this method private so that only the CLR
|
|
can call the method.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
public class MainClass {
|
|
public void Main ()
|
|
{
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example (type is not externally visible):
|
|
<code>
|
|
internal class MainClass {
|
|
public void Main ()
|
|
{
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example (method is not externally visible):
|
|
<code>
|
|
public class MainClass {
|
|
internal void Main ()
|
|
{
|
|
}
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.MarkAssemblyWithAssemblyVersionRule">
|
|
<summary>
|
|
This rule fires if an assembly does not contain a <c>[AssemblyVersion]</c>
|
|
attribute. Early and correct versioning of assemblies is easy and crucial for consumers
|
|
of your assemblies. Note that the <c>[AssemblyVersion]</c> should
|
|
match the <c>[AssemblyFileVersion]</c> attribute (if it exists).
|
|
</summary>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
[assembly: AssemblyVersion ("1.0.0.0")]
|
|
</code></example>
|
|
<remarks>This rule is available since Gendarme 2.2</remarks>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.MarkAssemblyWithCLSCompliantRule">
|
|
<summary>
|
|
This rule fires if an assembly does not contain a <c>[CLSCompliant]</c> attribute.
|
|
CLS compliant assemblies can be reused by any CLS-compliant language. It is a good practice
|
|
to declare your global CLS goal at the assembly level and, if needed, mark some types or
|
|
members that behave differently inside your assembly.
|
|
</summary>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
// by default everything in this assembly is CLS compliant
|
|
[assembly: CLSCompliant (true)]
|
|
</code></example>
|
|
<remarks>This rule is available since Gendarme 2.2</remarks>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.MarkAssemblyWithComVisibleRule">
|
|
<summary>
|
|
This rule fires if an assembly does not contain a <c>[ComVisible]</c> attribute.
|
|
Unless the assembly is designed with COM interoperability in mind it is better to declare
|
|
it as non-COM visible, i.e. <c>[ComVisible (false)]</c>.
|
|
</summary>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
// by default everything in this assembly is not visible to COM consumers
|
|
[assembly: ComVisible (false)]
|
|
</code></example>
|
|
<remarks>This rule is available since Gendarme 2.2</remarks>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.MissingAttributeUsageOnCustomAttributeRule">
|
|
<summary>
|
|
This rule verifies that every custom attribute (i.e. types that inherit from
|
|
<c>System.Attribute</c>) is decorated with an <c>[AttributeUsage]</c>
|
|
attribute to specify which kind of code instances of that custom attribute can be applied to.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
// this applies to everything - but the meaning is not clear
|
|
public sealed class SomeAttribute : Attribute {
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good examples:
|
|
<code>
|
|
// this clearly applies to everything
|
|
[AttributeUsage (AttributeTargets.All)]
|
|
public sealed class AttributeApplyingToAnything : Attribute {
|
|
}
|
|
// while this applies only to fields
|
|
[AttributeUsage (AttributeTargets.Field)]
|
|
public sealed class AttributeApplyingToFields : Attribute {
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.OperatorEqualsShouldBeOverloadedRule">
|
|
<summary>
|
|
This rule fires if a type overloads operator add <c>+</c>, or overloads operator subtract <c>-</c>,
|
|
or is a value type and overrides <c>Object.Equals</c>, but equals <c>==</c> is
|
|
not overloaded.
|
|
</summary>
|
|
<example>
|
|
Bad example (add/substract):
|
|
<code>
|
|
class DoesNotOverloadOperatorEquals {
|
|
public static int operator + (DoesNotOverloadOperatorEquals a)
|
|
{
|
|
return 0;
|
|
}
|
|
public static int operator - (DoesNotOverloadOperatorEquals a)
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Bad example (value type):
|
|
<code>
|
|
struct OverridesEquals {
|
|
public override bool Equals (object obj)
|
|
{
|
|
return base.Equals (obj);
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
struct OverloadsOperatorEquals {
|
|
public static int operator + (OverloadsOperatorEquals a)
|
|
{
|
|
return 0;
|
|
}
|
|
public static int operator - (OverloadsOperatorEquals a)
|
|
{
|
|
return 0;
|
|
}
|
|
public static bool operator == (OverloadsOperatorEquals a, OverloadsOperatorEquals b)
|
|
{
|
|
return a.Equals (b);
|
|
}
|
|
public override bool Equals (object obj)
|
|
{
|
|
return base.Equals (obj);
|
|
}
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.OverrideEqualsMethodRule">
|
|
<summary>
|
|
This rule warns when a type overloads the equality <c>==</c> operator but does not
|
|
override the <c>Object.Equals</c> method.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
class DoesNotOverrideEquals {
|
|
public static bool operator == (DoesNotOverloadOperatorEquals a, DoesNotOverloadOperatorEquals b)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
class OverridesEquals {
|
|
public static bool operator == (OverridesEquals a, OverridesEquals b)
|
|
{
|
|
return true;
|
|
}
|
|
public override bool Equals (object obj)
|
|
{
|
|
OverridesEquals other = (obj as OverridesEquals);
|
|
if (other == null) {
|
|
return false;
|
|
}
|
|
return (this == other);
|
|
}
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.PreferEventsOverMethodsRule">
|
|
<summary>
|
|
This rule checks for method names that suggest they are providing similar
|
|
functionality to .NET events. When possible the method(s) should be replaced
|
|
with a real event. If the methods are not using or providing
|
|
event-like features then they should be renamed since such names can confuse consumers
|
|
about what the method is really doing.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
public delegate void MouseUpCallback (int x, int y, MouseButtons buttons);
|
|
public class MouseController {
|
|
private MouseUpCallback mouse_up_callback;
|
|
public void RaiseMouseUp (Message msg)
|
|
{
|
|
if (mouse_up_callback != null) {
|
|
mouse_up_callback (msg.X, msg.Y, msg.Buttons);
|
|
}
|
|
}
|
|
public void ProcessMessage (Message msg)
|
|
{
|
|
switch (msg.Id) {
|
|
case MessageId.MouseUp: {
|
|
RaiseMouseUp (msg);
|
|
break;
|
|
}
|
|
// ... more ...
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
public class MouseController {
|
|
public event EventHandler<MessageEvent> MouseUp;
|
|
public void ProcessMessage (Message msg)
|
|
{
|
|
switch (msg.Id) {
|
|
case MessageId.MouseUp: {
|
|
EventHandler<MessageEvent> handler = MouseUp;
|
|
if (handler != null) {
|
|
handler (new MessageEvent (msg));
|
|
}
|
|
break;
|
|
}
|
|
// ... more ...
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.PreferIntegerOrStringForIndexersRule">
|
|
<summary>
|
|
This rule checks for indexer properties which use unusual types as indexes.
|
|
Recommended types include <c>Int32</c>, <c>Int64</c> and <c>String</c>.
|
|
Using other types can be OK if the indexer is providing an abstraction onto a
|
|
logical data store, but this is often not the case.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
public bool this [DateTime date] {
|
|
get {
|
|
return false;
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
public bool IsSomethingPlanned (DateTime date)
|
|
{
|
|
return false;
|
|
}
|
|
</code></example>
|
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.PreferUriOverStringRule">
|
|
<summary>
|
|
Checks methods and properties to ensure that System.Uri is used in place
|
|
of or in addition to strings where appropriate.
|
|
</summary>
|
|
<example>
|
|
Bad example 1:
|
|
<code>
|
|
string Uri { get; set; }
|
|
</code></example>
|
|
<example>
|
|
Bad example 2:
|
|
<code>
|
|
string GetUri () { return "http://www.mono-project.com"; }
|
|
</code></example>
|
|
<example>
|
|
Bad example 3:
|
|
<code>
|
|
void SendRequest (string url) {
|
|
...
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example 1:
|
|
<code>
|
|
Uri Uri { get; set; }
|
|
</code></example>
|
|
<example>
|
|
Bad example 2:
|
|
<code>
|
|
Uri GetUri () { return new Uri ("http://www.mono-project.com"); }
|
|
</code></example>
|
|
<example>
|
|
Good example 3:
|
|
<code>
|
|
void SendRequest (string url) {
|
|
SendRequest (new Uri(url));
|
|
}
|
|
void SendRequest (Uri url) {
|
|
...
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.PreferXmlAbstractionsRule">
|
|
<summary>
|
|
This rule fires if an externally visible method or property uses an <c>XmlDocument</c>,
|
|
<c>XPathDocument</c> or <c>XmlNode</c> argument. The problem with this is that it ties
|
|
your API to a specific implementation so it is difficult to change later. Instead use
|
|
abstract types like <c>IXPathNavigable</c>, <c>XmlReader</c>, <c>XmlWriter</c>, or subtypes
|
|
of <c>XmlNode</c>.
|
|
</summary>
|
|
<example>
|
|
Bad example (property):
|
|
<code>
|
|
public class Application {
|
|
public XmlDocument UserData {
|
|
get {
|
|
return userData;
|
|
}
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example (property):
|
|
<code>
|
|
public class Application {
|
|
public IXPathNavigable UserData {
|
|
get {
|
|
return userData;
|
|
}
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Bad example (method parameter):
|
|
<code>
|
|
public class Application {
|
|
public bool IsValidUserData (XmlDocument userData)
|
|
{
|
|
/* implementation */
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example (method parameter):
|
|
<code>
|
|
public class Application {
|
|
public bool IsValidUserData (XmlReader userData)
|
|
{
|
|
/* implementation */
|
|
}
|
|
}
|
|
</code></example>
|
|
<remarks>This rule is available since Gendarme 2.6</remarks>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.ProvideAlternativeNamesForOperatorOverloadsRule">
|
|
<summary>
|
|
The rule ensure that all overloaded operators are also accessible using named
|
|
alternatives because some languages, like VB.NET, cannot use overloaded operators.
|
|
For those languages named methods should be implemented that provide the same
|
|
functionality. This rule verifies that a named alternative exists for each overloaded operator.
|
|
<list type="bullet"><item><term>op_UnaryPlus</term><description>Plus</description></item><item><term>op_UnaryNegation</term><description>Negate</description></item><item><term>op_LogicalNot</term><description>LogicalNot</description></item><item><term>op_OnesComplement</term><description>OnesComplement</description></item></list><list type="bullet"><item><term>op_Increment</term><description>Increment</description></item><item><term>op_Decrement</term><description>Decrement</description></item><item><term>op_True</term><description>IsTrue</description></item><item><term>op_False</term><description>IsFalse</description></item></list><list type="bullet"><item><term>op_Addition</term><description>Add</description></item><item><term>op_Subtraction</term><description>Subtract</description></item><item><term>op_Multiply</term><description>Multiply</description></item><item><term>op_Division</term><description>Divide</description></item><item><term>op_Modulus</term><description>Modulus</description></item></list><list type="bullet"><item><term>op_BitwiseAnd</term><description>BitwiseAnd</description></item><item><term>op_BitwiseOr</term><description>BitwiseOr</description></item><item><term>op_ExclusiveOr</term><description>ExclusiveOr</description></item></list><list type="bullet"><item><term>op_LeftShift</term><description>LeftShift</description></item><item><term>op_RightShift</term><description>RightShift</description></item></list><list type="bullet"><item><term>op_Equality</term><description>Equals</description></item><item><term>op_Inequality</term><description>(not) Equals</description></item><item><term>op_GreaterThan</term><description>Compare</description></item><item><term>op_LessThan</term><description>Compare</description></item><item><term>op_GreaterThanOrEqual</term><description>Compare</description></item><item><term>op_LessThanOrEqual</term><description>Compare</description></item></list></summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
class DoesNotImplementAlternative {
|
|
public static int operator + (DoesNotOverloadOperatorEquals a, DoesNotOverloadOperatorEquals b)
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
class DoesImplementAdd {
|
|
public static int operator + (DoesImplementAdd a, DoesImplementAdd b)
|
|
{
|
|
return 0;
|
|
}
|
|
public int Add (DoesImplementAdd a)
|
|
{
|
|
return this + a;
|
|
}
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.ProvideTryParseAlternativeRule">
|
|
<summary>
|
|
This rule will warn on any type that provide <c>Parse(string...)</c>
|
|
method(s) without supplying <c>TryParse</c> alternative method(s).
|
|
Using a <c>TryParse</c> method is easier since it is less-error prone
|
|
(no need to handle all possible exceptions) and remove the performance
|
|
issue regarding throwing/catching exceptions.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
public struct Int32Tuple {
|
|
private int first;
|
|
private int second;
|
|
public Int32Tuple (int a, int b)
|
|
{
|
|
first = a;
|
|
second = b;
|
|
}
|
|
// documented to throw only Argument[Null]Exception or FormatException
|
|
static Int32Tuple Parse (string s)
|
|
{
|
|
if (s == null) {
|
|
throw new ArgumentNullException ("s");
|
|
} else if (s.Length == 0) {
|
|
throw new ArgumentException ("s");
|
|
} else {
|
|
string [] items = s.Split (':');
|
|
// without the try/catch it would be much harder to
|
|
// be 100% certain of all possible exceptions - like
|
|
// IndexOfOfRangeException and what Int32.Parse can throw
|
|
try {
|
|
int a = Int32.Parse (items [0]);
|
|
int b = Int32.Parse (items [1]);
|
|
return new Int32Tuple (a, b);
|
|
}
|
|
catch (Exception e) {
|
|
throw new FormatException ("Invalid data", e);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
public struct Int32Tuple {
|
|
private int first;
|
|
private int second;
|
|
public Int32Tuple (int a, int b)
|
|
{
|
|
first = a;
|
|
second = b;
|
|
}
|
|
// documented to throw only Argument[Null]Exception or FormatException
|
|
static Int32Tuple Parse (string s)
|
|
{
|
|
if (s == null) {
|
|
throw new ArgumentNullException ("s");
|
|
} else if (s.Length == 0) {
|
|
throw new ArgumentException ("s");
|
|
} else {
|
|
// re-implemented using the exception-less TryParse
|
|
Int32Tuple tuple;
|
|
if (!TryParse (s, out tuple))
|
|
throw new FormatException ("Invalid data");
|
|
return tuple;
|
|
}
|
|
}
|
|
static bool TryParse (string s, out Int32Tuple tuple)
|
|
{
|
|
tuple = new Int32Tuple ();
|
|
if (String.IsNullOrEmpty (s))
|
|
return false;
|
|
string [] items = s.Split (':');
|
|
if (items.Length != 2)
|
|
return false;
|
|
int a;
|
|
if (!Int32.TryParse (s, out a))
|
|
return false;
|
|
int b;
|
|
if (!Int32.TryParse (s, out b))
|
|
return false;
|
|
tuple.first = a;
|
|
tuple.second = b;
|
|
return true;
|
|
}
|
|
}
|
|
</code></example>
|
|
<remarks>This rule is available since Gendarme 2.8</remarks>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.StronglyTypeICollectionMembersRule">
|
|
<summary>
|
|
This rule checks that types which implements <c>System.Collections.ICollection</c> interface
|
|
have strongly typed version of the ICollection.CopyTo method.
|
|
This is needed to avoid casting every time this method is used.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
class Bad : ICollection {
|
|
public void CopyTo (Array array, int index)
|
|
{
|
|
// method code
|
|
}
|
|
// other ICollection members
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
class Good : ICollection {
|
|
public void ICollection.CopyTo (Array array, int index)
|
|
{
|
|
// method code
|
|
}
|
|
public void CopyTo (Exception [] array, int index)
|
|
{
|
|
((ICollection)this).CopyTo(array, index);
|
|
}
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.TypesShouldBeInsideNamespacesRule">
|
|
<summary>
|
|
This rule will fire if a type which is visible outside the assembly is not declared
|
|
within a namespace. Using namespaces greatly reduces the probability of name
|
|
collisions, allows tools such as auto-complete to operate better, and can make
|
|
the assemblies API clearer.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
using System;
|
|
public class Configuration {
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
using System;
|
|
namespace My.Stuff {
|
|
public class Configuration {
|
|
}
|
|
}
|
|
</code></example>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.UseFlagsAttributeRule">
|
|
<summary>
|
|
This rule will fire if an enum's values look like they are intended to
|
|
be composed together with the bitwise OR operator and the enum is not
|
|
decorated with <c>System.FlagsAttribute</c>. Using <c>FlagsAttribute</c> will
|
|
allow <c>System.Enum.ToString()</c> to return a better string when
|
|
values are ORed together and helps indicate to readers of the code
|
|
the intended usage of the enum.
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
[Serializable]
|
|
enum Options {
|
|
First = 1,
|
|
Second = 2,
|
|
Third = 4,
|
|
All = First | Second | Third,
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
[Flags]
|
|
[Serializable]
|
|
enum Options {
|
|
First = 1,
|
|
Second = 2,
|
|
Third = 4,
|
|
All = First | Second | Third,
|
|
}
|
|
</code></example>
|
|
<remarks>This rule is available since Gendarme 2.6</remarks>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.UseCorrectDisposeSignaturesRule">
|
|
<summary>
|
|
There is a convention that should be followed when implementing <c>IDisposable</c>. Part
|
|
of this convention is that Dispose methods should have specific signatures. In
|
|
particular an <c>IDisposable</c> type's Dispose methods should either be nullary or unary
|
|
with a bool argument, <c>Dispose ()</c> should not be virtual, <c>Dispose (bool)</c> should
|
|
not be public, and unsealed types should have a <c>protected virtual Dispose (bool)</c> method.
|
|
For more details see: [http://www.bluebytesoftware.com/blog/2005/04/08/DGUpdateDisposeFinalizationAndResourceManagement.aspx].
|
|
</summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
public class Unsealed : IDisposable
|
|
{
|
|
~Unsealed ()
|
|
{
|
|
Dispose (false);
|
|
}
|
|
public void Dispose ()
|
|
{
|
|
Dispose (true);
|
|
GC.SuppressFinalize (this);
|
|
}
|
|
// This is not virtual so resources in derived classes cannot be
|
|
// cleaned up in a timely fashion if Unsealed.Dispose () is called.
|
|
protected void Dispose (bool disposing)
|
|
{
|
|
if (!Disposed) {
|
|
// clean up my resources
|
|
Disposed = true;
|
|
}
|
|
}
|
|
protected bool Disposed {
|
|
get;
|
|
set;
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example:
|
|
<code>
|
|
public class Unsealed : IDisposable
|
|
{
|
|
// Unsealed classes should have a finalizer even if they do nothing
|
|
// in the Dispose (false) case to ensure derived classes are cleaned
|
|
// up properly.
|
|
~Unsealed ()
|
|
{
|
|
Dispose (false);
|
|
}
|
|
public Unsealed ()
|
|
{
|
|
}
|
|
public void Work ()
|
|
{
|
|
// In general all public methods should throw ObjectDisposedException
|
|
// if Dispose has been called.
|
|
if (Disposed) {
|
|
throw new ObjectDisposedException (GetType ().Name);
|
|
}
|
|
}
|
|
public void Dispose ()
|
|
{
|
|
Dispose (true);
|
|
GC.SuppressFinalize (this);
|
|
}
|
|
protected virtual void Dispose (bool disposing)
|
|
{
|
|
// Multiple Dispose calls should be OK.
|
|
if (!Disposed) {
|
|
if (disposing) {
|
|
// None of our fields have been finalized so it's safe to
|
|
// clean them up here.
|
|
}
|
|
// Our fields may have been finalized so we should only
|
|
// touch native fields (e.g. IntPtr or UIntPtr fields) here.
|
|
Disposed = true;
|
|
}
|
|
}
|
|
protected bool Disposed {
|
|
get;
|
|
private set;
|
|
}
|
|
}
|
|
</code></example>
|
|
<remarks>This rule is available since Gendarme 2.6</remarks>
|
|
</member>
|
|
<member name="T:Gendarme.Rules.Design.ImplementICloneableCorrectlyRule">
|
|
<summary>
|
|
This rule fires if you implement a <c>object Clone()</c> method without
|
|
implementing the <c>System.ICloneable</c> interface. Either change the
|
|
method so that it returns a better type than System.Object or implement
|
|
ICloneable.
|
|
<list type="bullet"><description>Note: Be sure to document the behavior of your
|
|
Clone method since the framework itself is not very clear, or consistent, between
|
|
shallow and deep cloning.</description></list></summary>
|
|
<example>
|
|
Bad example:
|
|
<code>
|
|
public class MyClass {
|
|
public object Clone ()
|
|
{
|
|
MyClass myClass = new MyClass ();
|
|
return myClass;
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example (ICloneable):
|
|
<code>
|
|
public class MyClass : ICloneable {
|
|
public object Clone ()
|
|
{
|
|
MyClass myClass = new MyClass ();
|
|
return myClass;
|
|
}
|
|
}
|
|
</code></example>
|
|
<example>
|
|
Good example (not returning System.Object):
|
|
<code>
|
|
public class MyClass {
|
|
public MyClass Clone ()
|
|
{
|
|
MyClass myClass = new MyClass ();
|
|
return myClass;
|
|
}
|
|
}
|
|
</code></example>
|
|
<remarks>Prior to Gendarme 2.2 this rule was named UsingCloneWithoutImplementingICloneableRule</remarks>
|
|
</member>
|
|
</members>
|
|
</doc>
|