Gendarme.Rules.Xamarin/lib/Gendarme.Rules.Performance....

1160 строки
46 KiB
XML

<?xml version="1.0"?>
<doc>
<assembly>
<name>Gendarme.Rules.Performance</name>
</assembly>
<members>
<member name="T:Gendarme.Rules.Performance.AvoidConcatenatingCharsRule">
<summary>
This rule will warn you if boxing is used to concatenate a string
since this will slow down your code and can be easily avoided. This
often happen when concatenating <c>System.String</c> and <c>System.Char</c>
values together. However the rule is not limited to check boxing on
<c>System.Char</c> since compilers often transform a character into its
integer value (e.g. 'a' == 61) and the same boxing issue exists on integers.
</summary>
<example>
Bad example:
<code>
public string PrintIndex (string a, char b)
{
// This is compiled into String.Concat(params object[])
// and requires boxing the 4 characters
Console.WriteLine ('[' + a + ',' + b + ']');
}
</code></example>
<example>
Good example:
<code>
public string PrintIndex (string a, char b)
{
// This is compiled into String.Concat(params string[])
// and no boxing is required
Console.WriteLine ("[" + a + "," + b.ToString () + "]");
}
</code></example>
<remarks>This rule is available since Gendarme 2.8</remarks>
</member>
<member name="T:Gendarme.Rules.Performance.AvoidLargeNumberOfLocalVariablesRule">
<summary>
This rule warns when the number of local variables exceed a maximum value (default is
64). Having a large amount of local variables makes it hard to generate code that
performs well and, likely, makes the code harder to understand.
</summary>
<remarks>This rule is available since Gendarme 2.0</remarks>
</member>
<member name="P:Gendarme.Rules.Performance.AvoidLargeNumberOfLocalVariablesRule.MaximumVariables">
<summary>The maximum number of local variables which methods may have without a defect being reported.</summary>
<remarks>Defaults to 64.</remarks>
</member>
<member name="T:Gendarme.Rules.Performance.AvoidLargeStructureRule">
<summary>
This rule will fire if a value type (struct in C#) is larger than a maximum value
(16 bytes by default). This is a problem because, unlike reference types, value
types are bitwise-copied whenever they are assigned to a variable or passed to
a method. If the type
cannot be reduced in size then it should be
turned into a reference type (class in C#).
</summary>
<example>
Bad example:
<code>
public struct BigArgb {
long a, r, g, b;
}
</code></example>
<example>
Good example:
<code>
public sealed class BigArgb {
long a, r, g, b;
}
</code></example>
<remarks>This rule is available since Gendarme 2.0</remarks>
</member>
<member name="P:Gendarme.Rules.Performance.AvoidLargeStructureRule.MaxSize">
<summary>The maximum size structs may be without a defect.</summary>
<remarks>Defaults to 16 bytes.</remarks>
</member>
<member name="T:Gendarme.Rules.Performance.AvoidLocalDataStoreSlotRule">
<summary>
This rule warns if a method use <c>LocalDataStoreSlot</c> to store or
retrieve data from Thread or Context Local Storage. The faster alternative
is to use <c>[ThreadStatic]</c> or <c>[ContextStatic]</c> attributes to avoid
extra calls and typecasts.
Also <c>[ThreadStatic]</c> is available on Silverlight while the
<c>LocalDataStoreSlot</c> API are not.
</summary>
<example>
Bad example (Thread Local Storage):
<code>
static void SetSharedKey (byte[] key)
{
LocalDataStoreSlot lds = Thread.AllocateNamedDataSlot ("shared-key");
lds.SetData (key.Clone ());
}
public byte[] SignData (byte[] data)
{
LocalDataStoreSlot lds = Thread.GetNamedDataSlot ("shared-key");
using (HMACSHA1 hmac = new HMACSHA1 (Thread.GetData (lds) as byte[])) {
return hmac.ComputeHash (data);
}
}
</code></example>
<example>
Good example (Thread Local Storage):
<code>
[ThreadStatic]
static byte[] shared_key;
static void SetSharedKey (byte[] key)
{
shared_key = (byte[]) key.Clone ();
}
public byte[] SignData (byte[] data)
{
using (HMACSHA1 hmac = new HMACSHA1 (shared_key)) {
return hmac.ComputeHash (data);
}
}
</code></example>
<remarks>This rule is available since Gendarme 2.8</remarks>
</member>
<member name="T:Gendarme.Rules.Performance.AvoidMethodWithLargeMaximumStackSizeRule">
<summary>
This rule fires if a method has a large maximum stack size (default is
100). Having a large maximum stack size makes it hard to generate code that
performs well and, likely, makes the code harder to understand.
</summary>
<remarks>This rule is available since Gendarme 2.6</remarks>
</member>
<member name="T:Gendarme.Rules.Performance.AvoidRepetitiveCallsToPropertiesRule">
<summary>
The rule warn if virtual, or unlikely to be inline-able, property getters
are called several times by a method. In most cases repetitive calls simply
requires more time without any gains since the result will always be identical.
You should ignore the reported defects if a different value is expected
each time the property is called (e.g. calling <c>DateTime.Now</c>).
</summary>
<example>
Bad example:
<code>
private int Report (IList list)
{
if (list.Count &gt; 1) {
DisplayList (list);
}
Console.WriteLine ("# items: {0}", list.Count);
return list.Count;
}
</code></example>
<example>
Good example:
<code>
private int Report (IList list)
{
int count = list.Count;
if (count &gt; 1) {
DisplayList (list);
}
Console.WriteLine ("# items: {0}", count);
return count;
}
</code></example>
<remarks>This rule is available since Gendarme 2.8</remarks>
</member>
<member name="P:Gendarme.Rules.Performance.AvoidRepetitiveCallsToPropertiesRule.InlineLimit">
<summary>
Methods with a code size below InlineLimit (20 by default)
are considered to be inline-able by the JIT.
</summary>
</member>
<member name="T:Gendarme.Rules.Performance.AvoidRepetitiveCastsRule">
<summary>
This rule fires if multiple casts are done on the same value, for the same type.
Casts are expensive so reducing them, by changing the logic or caching the
result, can help performance.
</summary>
<example>
Bad example:
<code>
foreach (object o in list) {
// first cast (is)
if (o is ICollection) {
// second cast (as) if item implements ICollection
Process (o as ICollection);
}
}
</code></example>
<example>
Good example:
<code>
foreach (object o in list) {
// a single cast (as) per item
ICollection c = (o as ICollection);
if (c != null) {
SingleCast (c);
}
}
</code></example>
<example>
Bad example:
<code>
// first cast (is):
if (o is IDictionary) {
// second cast if item implements IDictionary:
Process ((IDictionary) o);
// first cast (is):
} else if (o is ICollection) {
// second cast if item implements ICollection:
Process ((ICollection) o);
}
</code></example>
<example>
Good example:
<code>
// a single cast (as) per item
IDictionary dict;
ICollection col;
if ((dict = o as IDictionary) != null) {
SingleCast (dict);
} else if ((col = o as ICollection) != null) {
SingleCast (col);
}
</code></example>
<remarks>This rule is available since Gendarme 2.0</remarks>
</member>
<member name="T:Gendarme.Rules.Performance.AvoidReturningArraysOnPropertiesRule">
<summary>
This rule check for properties which return arrays. This can be a problem because
properties are supposed to execute very quickly so it's likely that this property
is returning a reference to the internal state of the object. This means that
the caller can change the object's internal state via a back-door channel which
is usually a very bad thing and it means that the array's contents may change
unexpectedly if the caller holds onto the array.
The preferred approach is to either return a read-only collection or to change
the property to a method and return a copy of the array (it's important to use
a method so that callers are not misled about the performance of the property).
</summary>
<example>
Bad example:
<code>
public byte[] Foo {
get {
// return the data inside the instance
return foo;
}
}
public byte[] Bar {
get {
// return a copy of the instance's data
// (this is bad because users expect properties to execute quickly)
return (byte[]) bar.Clone ();
}
}
</code></example>
<example>
Good example:
<code>
public byte[] GetFoo ()
{
return (byte[]) foo.Clone ();
}
public byte[] GetFoo ()
{
return (byte[]) bar.Clone ();
}
</code></example>
</member>
<member name="T:Gendarme.Rules.Performance.AvoidTypeGetTypeForConstantStringsRule">
<summary>
This rule warns when a method use <c>Type.GetType(string)</c> with a constant string.
Such calls requires reflection in order to return a <c>Type</c> instance and, for
known types, can be replaced with a much faster <c>typeof(x)</c>.
</summary>
<example>
Bad example:
<code>
booleanType = Type.GetType ("System.Boolean");
</code></example>
<example>
Good example:
<code>
booleanType = typeof (bool);
</code></example>
<remarks>This rule is available since Gendarme 2.0</remarks>
</member>
<member name="T:Gendarme.Rules.Performance.AvoidUncalledPrivateCodeRule">
<summary>
This rule will check for internally visible methods which are never called.
The rule will warn you if a private method isn't called in its declaring type or
if an internal method doesn't have any callers in the assembly or isn't invoked by
the runtime or a delegate.
</summary>
<example>
Bad example:
<code>
public class MyClass {
private void MakeSuff ()
{
// ...
}
public void Method ()
{
Console.WriteLine ("Foo");
}
}
</code></example>
<example>
Good example (removing unused code):
<code>
public class MyClass {
public void Method ()
{
Console.WriteLine ("Foo");
}
}
</code></example>
<example>
Good example (use the code):
<code>
public class MyClass {
private void MakeSuff ()
{
// ...
}
public void Method ()
{
Console.WriteLine ("Foo");
MakeSuff ();
}
}
</code></example>
</member>
<member name="T:Gendarme.Rules.Performance.AvoidUninstantiatedInternalClassesRule">
<summary>
This rule will fire if a type is only visible within its assembly, can be instantiated, but
is not instantiated. Such types are often leftover (dead code) or are debugging/testing
code and not required. However in some case the types might by needed, e.g. when
accessed thru reflection or if the <c>[InternalsVisibleTo]</c> attribute is used on the
assembly.
</summary>
<example>
Bad example:
<code>
// defined, but never instantiated
internal class MyInternalClass {
// ...
}
public class MyClass {
static void Main ()
{
// ...
}
}
</code></example>
<example>
Good example:
<code>
internal class MyInternalClass {
// ...
}
public class MyClass {
static void Main ()
{
MyInternalClass c = new MyInternalClass ();
// ...
}
}
</code></example>
</member>
<member name="T:Gendarme.Rules.Performance.AvoidUnnecessaryOverridesRule">
<summary>
This rule looks for overriding methods which just call the base method, and don't
define any additional attributes or security declarations.
</summary>
<example>
Bad example:
<code>
public override string ToString ()
{
return base.ToString ();
}
</code></example>
<example>
Good example (different attributes):
<code>
[FileIOPermission (SecurityAction.Demand, @"c:\dir\file")]
public override string ToString ()
{
return base.ToString ();
}
</code></example>
<example>
Good example (remove override):
<code>
/*public override string ToString ()
{
return base.ToString ();
}*/
</code></example>
</member>
<member name="T:Gendarme.Rules.Performance.AvoidUnneededCallsOnStringRule">
<summary>
This rule detects when some methods, like <c>Clone()</c>, <c>Substring(0)</c>,
<c>ToString()</c> or <c>ToString(IFormatProvider)</c>, are being called on a
string instance. Since these calls all return the original string they don't do anything
useful and should be carefully reviewed to see if they are working as intended and,
if they are, the method call can be removed.
</summary>
<example>
Bad example:
<code>
public void PrintName (string name)
{
Console.WriteLine ("Name: {0}", name.ToString ());
}
</code></example>
<example>
Good example:
<code>
public void PrintName (string name)
{
Console.WriteLine ("Name: {0}", name);
}
</code></example>
<remarks>Prior to Gendarme 2.0 this rule was more limited and named AvoidToStringOnStringsRule</remarks>
</member>
<member name="T:Gendarme.Rules.Performance.AvoidUnneededFieldInitializationRule">
<summary>
This rule looks for constructors that assign fields to their default value
(e.g. 0 for an integer, null for an object or a string). Since the CLR zero initializes
all values there is no need, under most circumstances, to assign default values.
Doing so only adds size to source code and in IL.
</summary>
<example>
Bad example:
<code>
public class Bad {
int i;
string s;
public Bad ()
{
i = 0;
s = null;
}
}
</code></example>
<example>
Good example:
<code>
public class Good {
int i;
string s;
public Good ()
{
// don't assign 'i' since it's already 0
// but we might prefer to assign a string to String.Empty
s = String.Empty;
}
}
</code></example>
<remarks>This rule is available since Gendarme 2.2</remarks>
</member>
<member name="T:Gendarme.Rules.Performance.AvoidUnneededUnboxingRule">
<summary>
This rule checks methods which unbox the same value type multiple times (i.e. the
value is copied from the heap into the stack). Because the copy is relatively expensive,
the code should be rewritten to minimize unboxes. For example, using a local variable
of the right value type should remove the need for more than one unbox instruction
per variable.
</summary>
<example>
Bad example:
<code>
public struct Message {
private int msg;
private IntPtr hwnd, lParam, wParam, IntPtr result;
public override bool Equals (object o)
{
bool result = (this.msg == ((Message) o).msg);
result &amp;= (this.hwnd == ((Message) o).hwnd);
result &amp;= (this.lParam == ((Message) o).lParam);
result &amp;= (this.wParam == ((Message) o).wParam);
result &amp;= (this.result == ((Message) o).result);
return result;
}
}
</code></example>
<example>
Good example:
<code>
public struct Message {
private int msg;
private IntPtr hwnd, lParam, wParam, IntPtr result;
public override bool Equals (object o)
{
Message msg = (Message) o;
bool result = (this.msg == msg.msg);
result &amp;= (this.hwnd == msg.hwnd);
result &amp;= (this.lParam == msg.lParam);
result &amp;= (this.wParam == msg.wParam);
result &amp;= (this.result == msg.result);
return result;
}
}
</code></example>
<remarks>This rule is available since Gendarme 2.0</remarks>
</member>
<member name="T:Gendarme.Rules.Performance.AvoidUnsealedConcreteAttributesRule">
<summary>
This rule fires if an attribute is defined which is both concrete (i.e. not abstract)
and unsealed. This is a performance problem because it means that
<c>System.Attribute.GetCustomAttribute</c> has to search the attribute type
hierarchy for derived types. To fix this either seal the type or make it abstract.
</summary>
<example>
Bad example:
<code>
[AttributeUsage (AttributeTargets.All)]
public class BadAttribute : Attribute {
}
</code></example>
<example>
Good example (sealed):
<code>
[AttributeUsage (AttributeTargets.All)]
public sealed class SealedAttribute : Attribute {
}
</code></example>
<example>
Good example (abstract and sealed):
<code>
[AttributeUsage (AttributeTargets.All)]
public abstract class AbstractAttribute : Attribute {
}
[AttributeUsage (AttributeTargets.All)]
public sealed class ConcreteAttribute : AbstractAttribute {
}
</code></example>
<remarks>Before Gendarme 2.0 this rule was named AvoidUnsealedAttributesRule.</remarks>
</member>
<member name="T:Gendarme.Rules.Performance.AvoidUnsealedUninheritedInternalTypeRule">
<summary>
This rule will fire for classes which are internal to the assembly and have no derived
classes, but are not <c>sealed</c>. Sealing the type clarifies the type hierarchy and
allows the compiler/JIT to perform optimizations such as eliding virtual method calls.
</summary>
<example>
Bad example:
<code>
// this one is correct since MyInheritedStuff inherits from this class
internal class MyBaseStuff {
}
// this one is bad, since no other class inherit from MyConcreteStuff
internal class MyInheritedStuff : MyBaseStuff {
}
</code></example>
<example>
Good example:
<code>
// this one is correct since the class is abstract
internal abstract class MyAbstractStuff {
}
// this one is correct since the class is sealed
internal sealed class MyConcreteStuff : MyAbstractStuff {
}
</code></example>
<remarks>This rule is available since Gendarme 2.0 and, before 2.2, was named AvoidUnsealedUninheritedInternalClassesRule</remarks>
</member>
<member name="T:Gendarme.Rules.Performance.AvoidUnusedParametersRule">
<summary>
This rule is used to ensure that all parameters in a method signature are being used.
The rule wont report a defect against the following:
<list><item><description>Methods that are referenced by a delegate;</description></item><item><description>Methods used as event handlers;</description></item><item><description>Abstract methods;</description></item><item><description>Virtual or overriden methods;</description></item><item><description>External methods (e.g. p/invokes)</description></item></list></summary>
<example>
Bad example:
<code>
public void MethodWithUnusedParameters (IEnumerable enumerable, int x)
{
foreach (object item in enumerable) {
Console.WriteLine (item);
}
}
</code></example>
<example>
Good example:
<code>
public void MethodWithUsedParameters (IEnumerable enumerable)
{
foreach (object item in enumerable) {
Console.WriteLine (item);
}
}
</code></example>
</member>
<member name="T:Gendarme.Rules.Performance.AvoidUnusedPrivateFieldsRule">
<summary>
This rule checks all private fields inside each type to see if some of them are not
being used. This could be a leftover from debugging or testing code or a more
serious typo where a wrong field is being used. In any case this makes the type bigger
than it needs to be which can affect performance when a large number of instances
exist.
</summary>
<example>
Bad example:
<code>
public class Bad {
int level;
bool b;
public void Indent ()
{
level++;
#if DEBUG
if (b) Console.WriteLine (level);
#endif
}
}
</code></example>
<example>
Good example:
<code>
public class Good {
int level;
#if DEBUG
bool b;
#endif
public void Indent ()
{
level++;
#if DEBUG
if (b) Console.WriteLine (level);
#endif
}
}
</code></example>
</member>
<member name="T:Gendarme.Rules.Performance.CompareWithEmptyStringEfficientlyRule">
<summary>
This rule will fire if a string is compared to <c>""</c> or <c>String.Empty</c>.
Instead use a <c>String.Length</c> test which should be a bit faster. Another
possibility (with .NET 2.0) is to use the static <c>String.IsNullOrEmpty</c> method.
<c>String.IsNullOrEmpty</c>.
</summary>
<example>
Bad example:
<code>
public void SimpleMethod (string myString)
{
if (myString.Equals (String.Empty)) {
}
}
</code></example>
<example>
Good example:
<code>
public void SimpleMethod (string myString)
{
if (myString.Length == 0) {
}
}
</code></example>
</member>
<member name="T:Gendarme.Rules.Performance.ConsiderCustomAccessorsForNonVisibleEventsRule">
<summary>
This rule looks for non-visible events to see if their add/remove accessors are
the default ones. The default, compiler generated, accessor is marked as synchronized
which means that the runtime will bracket them between <c>Monitor.Enter</c> and
<c>Monitor.Exit</c> calls. This is the safest approach unless, for non-visible events,
you have a performance bottleneck around the events. In this case you should review
if your code needs the locks or if you can provide an alternative to them.
</summary>
<example>
Bad example:
<code>
private event EventHandler&lt;TestEventArgs&gt; TimeCritical;
</code></example>
<example>
Good example:
<code>
static object TimeCriticalEvent = new object ();
EventHandlerList events = new EventHandlerList ();
private event EventHandler&lt;TestEventArgs&gt; TimeCritical {
add {
events.AddHandler (TimeCriticalEvent, value);
}
remove {
events.AddHandler (TimeCriticalEvent, value);
}
}
</code></example>
<remarks>This rule is available since Gendarme 2.0</remarks>
</member>
<member name="T:Gendarme.Rules.Performance.DoNotIgnoreMethodResultRule">
<summary>
This rule fires if a method is called that returns a new instance but that instance
is not used. This is a performance problem because it is wasteful to create and
collect objects which are never actually used. It may also indicate a logic problem.
Note that this rule currently only checks methods within a small number of System
types.
</summary>
<example>
Bad example:
<code>
public void GetName ()
{
string name = Console.ReadLine ();
// This is a bug: strings are (mostly) immutable so Trim leaves
// name untouched and returns a new string.
name.Trim ();
Console.WriteLine ("Name: {0}", name);
}
</code></example>
<example>
Good example:
<code>
public void GetName ()
{
string name = Console.ReadLine ();
name = name.Trim ();
Console.WriteLine ("Name: {0}", name);
}
</code></example>
</member>
<member name="T:Gendarme.Rules.Performance.RemoveUnneededFinalizerRule">
<summary>
This rule looks for types that have an empty finalizer (a.k.a. destructor in C# or
<c>Finalize</c> method). Finalizers that simply set fields to null are considered to be
empty because this does not help the garbage collection. You should remove the empty
finalizer to alleviate pressure on the garbage collector and finalizer thread.
</summary>
<example>
Bad example (empty):
<code>
class Bad {
~Bad ()
{
}
}
</code></example>
<example>
Bad example (only nulls fields):
<code>
class Bad {
object o;
~Bad ()
{
o = null;
}
}
</code></example>
<example>
Good example:
<code>
class Good {
object o;
}
</code></example>
<remarks>Prior to Gendarme 2.2 this rule was named EmptyDestructorRule</remarks>
</member>
<member name="T:Gendarme.Rules.Performance.UseSuppressFinalizeOnIDisposableTypeWithFinalizerRule">
<summary>
This rule will fire if a type implements <c>System.IDisposable</c> and has a finalizer
(called a destructor in C#), but the Dispose method does not call <c>System.GC.SuppressFinalize</c>.
Failing to do this should not cause properly written code to fail, but it does place a non-trivial
amount of extra pressure on the garbage collector and on the finalizer thread.
</summary>
<example>
Bad example:
<code>
class BadClass : IDisposable {
~BadClass ()
{
Dispose (false);
}
public void Dispose ()
{
// GC.SuppressFinalize is missing so the finalizer will be called
// which puts needless extra pressure on the garbage collector.
Dispose (true);
}
private void Dispose (bool disposing)
{
if (ptr != IntPtr.Zero) {
Free (ptr);
ptr = IntPtr.Zero;
}
}
[DllImport ("somelib")]
private static extern void Free (IntPtr ptr);
private IntPtr ptr;
}
</code></example>
<example>
Good example:
<code>
class GoodClass : IDisposable {
~GoodClass ()
{
Dispose (false);
}
public void Dispose ()
{
Dispose (true);
GC.SuppressFinalize (this);
}
private void Dispose (bool disposing)
{
if (ptr != IntPtr.Zero) {
Free (ptr);
ptr = IntPtr.Zero;
}
}
[DllImport ("somelib")]
private static extern void Free (IntPtr ptr);
private IntPtr ptr;
}
</code></example>
<remarks>Prior to Gendarme 2.2 this rule was named IDisposableWithDestructorWithoutSuppressFinalizeRule</remarks>
</member>
<member name="T:Gendarme.Rules.Performance.ImplementEqualsTypeRule">
<summary>
This rule looks for types that override <c>Object.Equals(object)</c> but do not
provide a <c>Equals(x)</c> overload using the type. Such an overload removes the
need to cast the object to the correct type. For value types this also removes the
costly boxing operations. Assemblies targeting .NET 2.0 (and later) should
also implement <c>System.IEquatable&lt;T&gt;</c>.
</summary>
<example>
Bad example:
<code>
public class Bad {
public override bool Equals (object obj)
{
return base.Equals (obj);
}
public override int GetHashCode ()
{
return base.GetHashCode ();
}
}
</code></example>
<example>
Good example:
<code>
// IEquatable&lt;T&gt; is only available since
// version 2.0 of the .NET framework
public class Good : IEquatable&lt;Good&gt; {
public override bool Equals (object obj)
{
return (obj as Good);
}
public bool Equals (Good other)
{
return (other != null);
}
public override int GetHashCode ()
{
return base.GetHashCode ();
}
}
</code></example>
<remarks>This rule is available since Gendarme 2.0</remarks>
</member>
<member name="T:Gendarme.Rules.Performance.MathMinMaxCandidateRule">
<summary>
This rule checks methods for code which seems to duplicate <c>Math.Min</c> or
<c>Math.Max</c>. The JIT can inline these methods and generate
better code for, at least some types, than it can for a custom inline
implementation.
</summary>
<example>
Bad example:
<code>
int max = (a &gt; b) ? a : b;
</code></example>
<example>
Good example:
<code>
int max = Math.Max (a, b);
</code></example>
<remarks>This rule is available since Gendarme 2.0</remarks>
</member>
<member name="T:Gendarme.Rules.Performance.OverrideValueTypeDefaultsRule">
<summary>
This rule checks all value types, except enumerations, to see if they use the default
implementation of <c>Equals(object)</c> and <c>GetHashCode()</c> methods. While
<c>ValueType</c> implementations work for any value type they do so at the expense of
performance (the default implementation uses reflection to access fields). You can easily
override both methods
with much faster code since you know all meaningful fields inside your structure.
At the same time you should also provide, if your language allows it, operator overloads
for equality (<c>op_Equality</c>, <c>==</c>) and inequality (<c>op_Inequality</c>,
<c>!=</c>).
</summary>
<example>
Bad example:
<code>
public struct Coord {
int X, Y, Z;
}
</code></example>
<example>
Good example:
<code>
public struct Coord {
int X, Y, Z;
public override bool Equals (object obj)
{
if (obj == null) {
return false;
}
Coord c = (Coord)obj;
return ((X == c.X) &amp;&amp; (Y == c.Y) &amp;&amp; (Z == c.Z));
}
public override int GetHashCode ()
{
return X ^ Y ^ Z;
}
public static bool operator == (Coord left, Coord right)
{
return left.Equals (right);
}
public static bool operator != (Coord left, Coord right)
{
return !left.Equals (right);
}
}
</code></example>
<remarks>This rule is available since Gendarme 2.0</remarks>
</member>
<member name="T:Gendarme.Rules.Performance.PreferCharOverloadRule">
<summary>
This rule looks for calls to <c>String</c> methods that use <b>String</b>
parameters when a <c>Char</c> parameter could have been used. Using the
<c>Char</c> overload is preferred because it will be faster.
Note, however, that this may result in subtly different behavior on versions of
.NET before 4.0: the string overloads do a culture based comparison using
<c>CultureInfo.CurrentCulture</c> and the char methods do an ordinal
comparison (a simple compare of the character values). This can result in
a change of behavior (for example the two can produce different results when
precomposed characters are used). If this is important it is best to use an
overload that allows StringComparison or CultureInfo to be explicitly specified
see [http://msdn.microsoft.com/en-us/library/ms973919.aspx#stringsinnet20_topic4]
for more details.
With .NET 4.0 <c>String</c>'s behavior will change and the various methods
will be made more consistent. In particular the comparison methods will be changed
so that they all default to doing an ordinal comparison.
</summary>
<example>
Bad example:
<code>
if (s.IndexOf (":") == -1) {
Console.WriteLine ("no separator found");
}
</code></example>
<example>
Good example:
<code>
if (s.IndexOf (':') == -1) {
Console.WriteLine ("no separator found");
}
</code></example>
<remarks>This rule is available since Gendarme 2.4</remarks>
</member>
<member name="T:Gendarme.Rules.Performance.PreferInterfaceConstraintOnGenericParameterForPrimitiveInterfaceRule">
<summary>
This rule fires if a method use an interface of a primitive type as parameter.
(IComparable, IFormattable, IConvertible, IComparable&lt;T&gt;, IEquatable&lt;int&gt; ...)
Using generic method with an interface constraint instead avoid boxing of value
type when calling the method.
</summary>
<example>
Bad example:
<code>
public bool GreaterThan (IComparable arg1, IComparable arg2)
{
return arg1.CompareTo (arg2) &gt; 0
}
</code></example>
<example>
Good example:
<code>
public bool GreaterThan&lt;T&gt; (T arg1, T arg2) where T : IComparable
{
return arg1.CompareTo (arg2) &gt; 0
}
</code></example>
</member>
<member name="T:Gendarme.Rules.Performance.PreferLiteralOverInitOnlyFieldsRule">
<summary>
This rule looks for <c>InitOnly</c> fields (<c>readonly</c> in C#) that could be
turned into <c>Literal</c> (<c>const</c> in C#) because their value is known at
compile time. <c>Literal</c> fields don't need to be initialized (i.e. they don't
force the compiler to add a static constructor to the type) resulting in less code and the
value (not a reference to the field) will be directly used in the IL (which is OK
if the field has internal visibility, but is often problematic if the field is visible outside
the assembly).
</summary>
<example>
Bad example:
<code>
public class ClassWithReadOnly {
static readonly int One = 1;
}
</code></example>
<example>
Good example:
<code>
public class ClassWithConst
{
const int One = 1;
}
</code></example>
<remarks>This rule is available since Gendarme 2.2</remarks>
</member>
<member name="T:Gendarme.Rules.Performance.RemoveUnusedLocalVariablesRule">
<summary>
This rule looks for unused local variables inside methods. This can leads to larger
code (IL) size and longer JIT time, but note that some optimizing compilers
can remove the locals so they won't be reported even if you can still see them in
the source code. This could also be a typo in the source were a value is assigned
to the wrong variable.
</summary>
<example>
Bad example:
<code>
bool DualCheck ()
{
bool b1 = true;
bool b2 = CheckDetails ();
if (b2) {
// typo: a find-replace changed b1 into b2
b2 = CheckMoreDetails ();
}
return b2 &amp;&amp; b2;
}
</code></example>
<example>
Good example:
<code>
bool DualCheck ()
{
bool b1 = true;
bool b2 = CheckDetails ();
if (b2) {
b1 = CheckMoreDetails ();
}
return b1 &amp;&amp; b2;
}
</code></example>
<remarks>This rule is available since Gendarme 2.0</remarks>
</member>
<member name="T:Gendarme.Rules.Performance.ReviewLinqMethodRule">
<summary>
Linq extension methods operate on sequences of values so they generally
have linear time complexity. However you may be able to achieve better
than linear time performance if you use a less general method or take
advantage of a method provided by an <c>Sytem.Collections.Generic.IEnumerable&lt;T&gt;</c>
subclass.
</summary>
<example>
Bad example:
<code>
public string FirstOrMissing (IEnumerable&lt;string&gt; sequence, string missing)
{
// Count () is O(n)
if (sequence.Count () &gt; 0) {
return sequence.First ();
}
return missing;
}
public void Append (List&lt;string&gt; lines, string line)
{
// Last () is O(n)
if (lines.Count == 0 || lines.Last () != line) {
lines.Add (line);
}
}
</code></example>
<example>
Good example:
<code>
public string FirstOrMissing (IEnumerable&lt;string&gt; sequence, string missing)
{
// We don't need an exact count so we can use the O(1) Any () method.
if (sequence.Any ()) {
return sequence.First ();
}
return missing;
}
public void Append (List&lt;string&gt; lines, string line)
{
// Lines is a List so we can use the O(1) subscript operator instead of
// the Last () method.
if (lines.Count == 0 || lines [lines.Count - 1] != line) {
lines.Add (line);
}
}
</code></example>
<remarks>This rule is available since Gendarme 2.6</remarks>
</member>
<member name="T:Gendarme.Rules.Performance.UseIsOperatorRule">
<summary>
This rule looks for complex cast operations (e.g. a <c>as</c>
with a <c>null</c> check) that can be simplified using the <c>is</c> operator
(C# syntax). Note: in some case a compiler, like [g]mcs, can optimize the code and
generate IL identical to a <c>is</c> operator. In this case the rule will not report
an error even if you could see one while looking the at source code.
</summary>
<example>
Bad example:
<code>
bool is_my_type = (my_instance as MyType) != null;
</code></example>
<example>
Good example:
<code>
bool is_my_type = (my_instance is MyType);
</code></example>
<remarks>This rule is available since Gendarme 2.0</remarks>
</member>
<member name="T:Gendarme.Rules.Performance.UseStringEmptyRule">
<summary>
This rule checks for methods that are using the literal <c>""</c> instead of the
<c>String.Empty</c> field. You'll get slighly better performance by using
<c>String.Empty</c>. Note that in some cases, e.g. in a <c>switch/case</c> statement,
you cannot use a field, so <c>""</c> must be used instead of <c>String.Empty</c>.
</summary>
<example>
Bad example:
<code>
string s = "";
</code></example>
<example>
Good example:
<code>
string s = String.Empty;
</code></example>
</member>
<member name="T:Gendarme.Rules.Performance.UseTypeEmptyTypesRule">
<summary>
This rule fires if a zero length array of <c>System.Type</c> is created.
This value is so often required by the framework API that the <c>System.Type</c> includes
an <c>EmptyTypes</c> field. Using this field avoids the memory allocation (and GC tracking)
of your own array.
</summary>
<example>
Bad example:
<code>
ConstructorInfo ci = type.GetConstructor (new Type[0]);
</code></example>
<example>
Good example:
<code>
ConstructorInfo ci = type.GetConstructor (Type.EmptyTypes);
</code></example>
<remarks>This rule is available since Gendarme 2.0</remarks>
</member>
</members>
</doc>