Gendarme.Rules.Xamarin/lib/Gendarme.Rules.Design.dll.doc

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 &lt; 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&lt;EventArgs&gt; 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&lt;T&gt;</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&lt;string&gt; 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&lt;string&gt; list;
public Holder ()
{
list = new List&lt;string&gt; ();
}
public string Name { get; set; }
public ICollection&lt;string&gt; 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 &lt;&lt; 15
}
</code></example>
<example>
Good example:
<code>
public enum SmallEnum {
Zero,
One
}
[Flags]
public enum SmallFlag {
One = 1,
// ...
Sixteen = 1 &lt;&lt; 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>&lt;</c> and <c>&gt;</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 &gt; (Comparable left, Comparable right)
{
return (left.x &gt; right.x);
}
static public bool operator &lt; (Comparable left, Comparable right)
{
return (left.x &lt; 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&lt;MessageEvent&gt; MouseUp;
public void ProcessMessage (Message msg)
{
switch (msg.Id) {
case MessageId.MouseUp: {
EventHandler&lt;MessageEvent&gt; 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>