Initial import
This commit is contained in:
Родитель
9f50b38a6d
Коммит
f14ab871db
|
@ -1,5 +1,5 @@
|
||||||
# Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
|
# Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
|
||||||
[Bb]in/
|
[Bb]in/*Xamarin*
|
||||||
[Oo]bj/
|
[Oo]bj/
|
||||||
|
|
||||||
# mstest test results
|
# mstest test results
|
||||||
|
@ -88,8 +88,10 @@ csx
|
||||||
# Windows Store app package directory
|
# Windows Store app package directory
|
||||||
AppPackages/
|
AppPackages/
|
||||||
|
|
||||||
|
# OS X
|
||||||
|
*.DS_Store
|
||||||
|
|
||||||
# Others
|
# Others
|
||||||
[Bb]in
|
|
||||||
[Oo]bj
|
[Oo]bj
|
||||||
sql
|
sql
|
||||||
TestResults
|
TestResults
|
||||||
|
|
Двоичный файл не отображается.
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -0,0 +1,909 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<doc>
|
||||||
|
<assembly>
|
||||||
|
<name>Gendarme.Rules.BadPractice</name>
|
||||||
|
</assembly>
|
||||||
|
<members>
|
||||||
|
<member name="T:Gendarme.Rules.BadPractice.AvoidAssemblyVersionMismatchRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks that the <c>[AssemblyVersion]</c> matches the <c>[AssemblyFileVersion]</c>
|
||||||
|
when both are present inside an assembly. Having different version numbers in both
|
||||||
|
attributes can be confusing once the application is deployed.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[assembly: AssemblyVersion ("2.2.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion ("1.0.0.0")]
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
[assembly: AssemblyVersion ("2.2.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion ("2.2.0.0")]
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.2</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.BadPractice.AvoidCallingProblematicMethodsRule">
|
||||||
|
<summary>
|
||||||
|
This rule warns about methods that calls into potentially dangerous API of the .NET
|
||||||
|
framework. If possible try to avoid the API (there are generally safer ways to do the
|
||||||
|
same) or at least make sure your code can be safely called from others.
|
||||||
|
<list type="bullet"><item><description><c>System.GC::Collect()</c></description></item><item><description><c>System.Threading.Thread::Suspend()</c> and <c>Resume()</c></description></item><item><description><c>System.Runtime.InteropServices.SafeHandle::DangerousGetHandle()</c></description></item><item><description><c>System.Reflection.Assembly::LoadFrom()</c>, <c>LoadFile()</c> and
|
||||||
|
<c>LoadWithPartialName()</c></description></item><item><description><c>System.Type::InvokeMember()</c> when used with
|
||||||
|
<c>BindingFlags.NonPublic</c></description></item></list></summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public void Load (string filename)
|
||||||
|
{
|
||||||
|
Assembly a = Assembly.LoadFile (filename);
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public void Load (string filename)
|
||||||
|
{
|
||||||
|
AssemblyName aname = AssemblyName.GetAssemblyName (filename);
|
||||||
|
// ensure it's the assembly you expect (e.g. public key, version...)
|
||||||
|
Assembly a = Assembly.Load (aname);
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.BadPractice.AvoidNullCheckWithAsOperatorRule">
|
||||||
|
<summary>
|
||||||
|
The rule will detect if a null check is done before using the <c>as</c> operator.
|
||||||
|
This null check is not needed, a <c>null</c> instance will return <c>null</c>,
|
||||||
|
and the code will need to deal with <c>as</c> returning a null value anyway.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public string AsString (object obj)
|
||||||
|
{
|
||||||
|
return (o == null) ? null : o as string;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public string AsString (object obj)
|
||||||
|
{
|
||||||
|
return (o as string);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.BadPractice.AvoidVisibleConstantFieldRule">
|
||||||
|
<summary>
|
||||||
|
This rule looks for constant fields which are visible outside the current assembly.
|
||||||
|
Such fields, if used outside the assemblies, will have their value (not the field
|
||||||
|
reference) copied into the other assembly. Changing the field's value requires that all
|
||||||
|
assemblies which use the field to be recompiled. Declaring the field
|
||||||
|
as <c>static readonly</c>, on the other hand, allows the value to be changed
|
||||||
|
without requiring that client assemblies be recompiled.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
// if this fields is used inside another assembly then
|
||||||
|
// the integer 42, not the field, will be baked into it
|
||||||
|
public const int MagicNumber = 42;
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
// if this field is used inside another assembly then
|
||||||
|
// that assembly will reference the field instead of
|
||||||
|
// embedding the value
|
||||||
|
static public readonly int MagicNumber = 42;
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.BadPractice.CheckNewExceptionWithoutThrowingRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for exception objects which are created but not thrown, not returned,
|
||||||
|
and not passed to another method as an argument.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
void MissingThrow (object arg)
|
||||||
|
{
|
||||||
|
if (arg == null) {
|
||||||
|
new ArgumentNullException ("arg");
|
||||||
|
}
|
||||||
|
DoWork (arg);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good examples:
|
||||||
|
<code>
|
||||||
|
void Throw (object arg)
|
||||||
|
{
|
||||||
|
if (arg == null) {
|
||||||
|
throw new ArgumentNullException ("arg");
|
||||||
|
}
|
||||||
|
DoWork (arg);
|
||||||
|
}
|
||||||
|
Exception CreateException ()
|
||||||
|
{
|
||||||
|
return new Exception ();
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.BadPractice.CheckNewThreadWithoutStartRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for threads which are created but not started, or returned or passed
|
||||||
|
to another method as an argument.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
void UnusedThread ()
|
||||||
|
{
|
||||||
|
Thread thread = new Thread (threadStart);
|
||||||
|
thread.Name = "Thread 1";
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good examples:
|
||||||
|
<code>
|
||||||
|
void Start ()
|
||||||
|
{
|
||||||
|
Thread thread = new Thread (threadStart);
|
||||||
|
thread.Name = "Thread 1";
|
||||||
|
thread.Start ();
|
||||||
|
}
|
||||||
|
Thread InitializeThread ()
|
||||||
|
{
|
||||||
|
Thread thread = new Thread (threadStart);
|
||||||
|
thread.Name = "Thread 1";
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.BadPractice.CloneMethodShouldNotReturnNullRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for <c>Clone()</c> methods which return <c>null</c>.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public class MyClass : ICloneable {
|
||||||
|
public object Clone ()
|
||||||
|
{
|
||||||
|
MyClass myClass = new MyClass ();
|
||||||
|
// set some internals
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public class MyClass : ICloneable {
|
||||||
|
public object Clone ()
|
||||||
|
{
|
||||||
|
MyClass myClass = new MyClass ();
|
||||||
|
// set some internals
|
||||||
|
return myClass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.BadPractice.ConstructorShouldNotCallVirtualMethodsRule">
|
||||||
|
<summary>
|
||||||
|
This rule warns the developer if any virtual methods are called in the constructor
|
||||||
|
of a non-sealed type. The problem is that if a derived class overrides the method
|
||||||
|
then that method will be called before the derived constructor has had a chance
|
||||||
|
to run. This makes the code quite fragile.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
class A {
|
||||||
|
public A ()
|
||||||
|
{
|
||||||
|
this.DoSomething ();
|
||||||
|
}
|
||||||
|
protected virtual void DoSomething ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class B : A {
|
||||||
|
private int x;
|
||||||
|
public B ()
|
||||||
|
{
|
||||||
|
x = 10;
|
||||||
|
}
|
||||||
|
protected override void DoSomething ()
|
||||||
|
{
|
||||||
|
Console.WriteLine (x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
B b = new B (); // outputs 0 because B's constructor hasn't been called yet
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
class A {
|
||||||
|
public void Run ()
|
||||||
|
{
|
||||||
|
this.DoSomething ();
|
||||||
|
}
|
||||||
|
protected virtual void DoSomething ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class B : A {
|
||||||
|
private int x;
|
||||||
|
public B ()
|
||||||
|
{
|
||||||
|
x = 10;
|
||||||
|
}
|
||||||
|
protected override void DoSomething ()
|
||||||
|
{
|
||||||
|
Console.WriteLine (x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
B b = new B ();
|
||||||
|
b.Run (); // outputs 10 as intended
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.BadPractice.DisableDebuggingCodeRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for non-console applications which contain calls to <c>Console.WriteLine</c>.
|
||||||
|
These are often used as debugging aids but such code should be removed or disabled in
|
||||||
|
the released version. If you don't want to remove it altogether you can place it inside a method
|
||||||
|
decorated with <c>[Conditional ("DEBUG")]</c>, use <c>Debug.WriteLine</c>, use
|
||||||
|
<c>Trace.WriteLine</c>, or use the preprocessor. But note that TRACE is often enabled
|
||||||
|
in release builds so if you do use that you'll probably want to use a config file to remove
|
||||||
|
the default trace listener.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
private byte[] GenerateKey ()
|
||||||
|
{
|
||||||
|
byte[] key = new byte[16];
|
||||||
|
rng.GetBytes (key);
|
||||||
|
Console.WriteLine ("debug key = {0}", BitConverter.ToString (key));
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (removed):
|
||||||
|
<code>
|
||||||
|
private byte[] GenerateKey ()
|
||||||
|
{
|
||||||
|
byte[] key = new byte[16];
|
||||||
|
rng.GetBytes (key);
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (changed):
|
||||||
|
<code>
|
||||||
|
private byte[] GenerateKey ()
|
||||||
|
{
|
||||||
|
byte[] key = new byte[16];
|
||||||
|
rng.GetBytes (key);
|
||||||
|
Debug.WriteLine ("debug key = {0}", BitConverter.ToString (key));
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.BadPractice.DoNotDecreaseVisibilityRule">
|
||||||
|
<summary>
|
||||||
|
The rule detect when a method visibility is decreased in an inherited type.
|
||||||
|
Decreasing visibility does not prevent calling the base class method unless
|
||||||
|
the type is <c>sealed</c>. Note that some language (but not C#) will allow
|
||||||
|
you to seal, e.g. <c>final</c>, the method without an <c>override</c>.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public class Base {
|
||||||
|
public void Public ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class BadInheritor : Base {
|
||||||
|
private new void Public ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (do not hide):
|
||||||
|
<code>
|
||||||
|
public class Inheritor : Base {
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (sealed type):
|
||||||
|
<code>
|
||||||
|
public sealed class Inheritor : Base {
|
||||||
|
private new void Public ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.BadPractice.DoNotForgetNotImplementedMethodsRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for short methods that throw a <c>System.NotImplementedException</c>
|
||||||
|
exception. It's likely a method that has not yet been implemented and should not be
|
||||||
|
forgotten by the developer before a release.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
private void Save ()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException ("pending final format");
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.BadPractice.DoNotUseEnumIsAssignableFromRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for calls to <c>typeof (Enum).IsAssignableFrom (type)</c> that
|
||||||
|
can be simplified to <c>type.IsEnum</c>.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
if (typeof (Enum).IsAssignableFrom (type)) {
|
||||||
|
// then the type is an enum
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
if (type.IsEnum) {
|
||||||
|
// then the type is an enum.
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.6</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.BadPractice.DoNotUseGetInterfaceToCheckAssignabilityRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for calls to <c>Type.GetInterface</c> that look like they query if
|
||||||
|
a type is supported, i.e. the result is only used to compare against <c>null</c>.
|
||||||
|
The problem is that only assembly qualified names uniquely identify a type so if
|
||||||
|
you just use the interface name or even just the name and namespace you may
|
||||||
|
get unexpected results.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
if (type.GetInterface ("IConvertible") != null) {
|
||||||
|
// then the type can be assigned to IConvertible
|
||||||
|
// but what if there is another IConvertible in there ?!?
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
if (typeof (IConvertible).IsAssignableFrom (type)) {
|
||||||
|
// then the type can be assigned to IConvertible
|
||||||
|
// without a doubt!
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.2</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.BadPractice.EqualsShouldHandleNullArgRule">
|
||||||
|
<summary>
|
||||||
|
This rule ensures that <c>Equals(object)</c> methods return <c>false</c> when the
|
||||||
|
object parameter is <c>null</c>.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public bool Equals (object obj)
|
||||||
|
{
|
||||||
|
// this would throw a NullReferenceException instead of returning false
|
||||||
|
return ToString ().Equals (obj.ToString ());
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public override bool Equals (object obj)
|
||||||
|
{
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return ToString ().Equals (obj.ToString ());
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.BadPractice.GetEntryAssemblyMayReturnNullRule">
|
||||||
|
<summary>
|
||||||
|
This rule warns when an assembly without an entry point (i.e. a dll or library) calls
|
||||||
|
<c>Assembly.GetEntryAssembly ()</c>. This call is problematic since it will always
|
||||||
|
return <c>null</c> when called from outside the root (main) application domain. This may
|
||||||
|
become a problem inside libraries that can be used, for example, inside ASP.NET
|
||||||
|
applications.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
// this will throw a NullReferenceException from an ASP.NET page
|
||||||
|
Response.WriteLine (Assembly.GetEntryAssembly ().CodeBase);
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public class MainClass {
|
||||||
|
static void Main ()
|
||||||
|
{
|
||||||
|
Console.WriteLine (Assembly.GetEntryAssembly ().CodeBase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.BadPractice.ObsoleteMessagesShouldNotBeEmptyRule">
|
||||||
|
<summary>
|
||||||
|
This rule warns if any type (including classes, structs, enums, interfaces and
|
||||||
|
delegates), field, property, events, method and constructor are decorated with
|
||||||
|
an empty <c>[Obsolete]</c> attribute because the attribute is much more helpful
|
||||||
|
if it includes advice on how to deal with the situation (e.g. the new recommended
|
||||||
|
API to use).
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[Obsolete]
|
||||||
|
public byte[] Key {
|
||||||
|
get {
|
||||||
|
return (byte[]) key.Clone ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
[Obsolete ("Use the new GetKey() method since properties should not return arrays.")]
|
||||||
|
public byte[] Key {
|
||||||
|
get {
|
||||||
|
return (byte[]) key.Clone ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.BadPractice.OnlyUseDisposeForIDisposableTypesRule">
|
||||||
|
<summary>
|
||||||
|
To avoid confusing developers methods named Dispose should be
|
||||||
|
reserved for types that implement IDisposable.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
internal sealed class Worker
|
||||||
|
{
|
||||||
|
// This class uses one or more temporary files to do its work.
|
||||||
|
private List<string> files = new List<string> ();
|
||||||
|
// This is confusing: developers will think they can do things
|
||||||
|
// like use the instance with a using statement.
|
||||||
|
public void Dispose ()
|
||||||
|
{
|
||||||
|
foreach (string path in files) {
|
||||||
|
File.Delete (path);
|
||||||
|
}
|
||||||
|
files.Clear ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
internal sealed class Worker
|
||||||
|
{
|
||||||
|
// This class uses one or more temporary files to do its work.
|
||||||
|
private List<string> files = new List<string> ();
|
||||||
|
public void Reset ()
|
||||||
|
{
|
||||||
|
foreach (string path in files) {
|
||||||
|
File.Delete (path);
|
||||||
|
}
|
||||||
|
files.Clear ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.6</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.BadPractice.PreferEmptyInstanceOverNullRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks that all methods and properties which return a string, an array,
|
||||||
|
a collection, or an enumerable do not return <c>null</c>.
|
||||||
|
It is usually better to return an empty instance, as this allows
|
||||||
|
the caller to use the result without having to perform a null-check first.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example (string):
|
||||||
|
<code>
|
||||||
|
public string DisplayName {
|
||||||
|
get {
|
||||||
|
if (IsAnonymous) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (string):
|
||||||
|
<code>
|
||||||
|
public string DisplayName {
|
||||||
|
get {
|
||||||
|
if (IsAnonymous) {
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Bad example (array):
|
||||||
|
<code>
|
||||||
|
public int [] GetOffsets ()
|
||||||
|
{
|
||||||
|
if (!store.HasOffsets) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
store.LoadOffsets ();
|
||||||
|
return store.Offsets;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (array):
|
||||||
|
<code>
|
||||||
|
static const int [] Empty = new int [0];
|
||||||
|
public int [] GetOffsets ()
|
||||||
|
{
|
||||||
|
if (!store.HasOffsets) {
|
||||||
|
return Empty;
|
||||||
|
}
|
||||||
|
store.LoadOffsets ();
|
||||||
|
return store.Offsets.ToArray ();
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Bad example (enumerable):
|
||||||
|
<code>
|
||||||
|
public IEnumerable<int> GetOffsets ()
|
||||||
|
{
|
||||||
|
if (!store.HasOffsets) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
store.LoadOffsets ();
|
||||||
|
return store.Offsets;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (enumerable):
|
||||||
|
<code>
|
||||||
|
public IEnumerable<int> GetOffsets ()
|
||||||
|
{
|
||||||
|
if (!store.HasOffsets) {
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
store.LoadOffsets ();
|
||||||
|
foreach (int offset in store.Offsets) {
|
||||||
|
yield return offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.4</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.BadPractice.PreferParamsArrayForVariableArgumentsRule">
|
||||||
|
<summary>
|
||||||
|
The rule warns for any method that use the (semi-documented) <c>vararg</c>
|
||||||
|
calling convention (e.g. <c>__arglist</c> in C#) and that is not used for
|
||||||
|
interoperability (i.e. pinvoke to unmanaged code).
|
||||||
|
Using <c>params</c> (C#) can to achieve the same objective while <c>vararg</c>
|
||||||
|
is not CLS compliant. The later will limit the usability of the method to CLS
|
||||||
|
compliant language (e.g. Visual Basic does not support <c>vararg</c>.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public void ShowItems_Bad (string header, __arglist)
|
||||||
|
{
|
||||||
|
Console.WriteLine (header);
|
||||||
|
ArgIterator args = new ArgIterator (__arglist);
|
||||||
|
for (int i = 0; i < args.GetRemainingCount (); i++) {
|
||||||
|
Console.WriteLine (__refvalue (args.GetNextArg (), string));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public void ShowItems (string header, params string [] items)
|
||||||
|
{
|
||||||
|
Console.WriteLine (header);
|
||||||
|
for (int i = 0; i < items.Length; i++) {
|
||||||
|
Console.WriteLine (items [i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (interoperability):
|
||||||
|
<code>
|
||||||
|
[DllImport ("libc.dll")]
|
||||||
|
static extern int printf (string format, __arglist);
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.8</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.BadPractice.PreferTryParseRule">
|
||||||
|
<summary>
|
||||||
|
This rule will warn you if a method use a <c>Parse</c> method when an
|
||||||
|
alternative <c>TryParse</c> method is available. A <c>Parser</c> method,
|
||||||
|
when using correctly, requires you to deal with multiple exceptions (a
|
||||||
|
complete list likely not easily available) or catching all exceptions (bad).
|
||||||
|
Also the throwing/catching of exceptions can kill performance.
|
||||||
|
The <c>TryParse</c> method allow simpler code without the performance penality.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example (no validation):
|
||||||
|
<code>
|
||||||
|
bool ParseLine (string line)
|
||||||
|
{
|
||||||
|
string values = line.Split (',');
|
||||||
|
if (values.Length == 3) {
|
||||||
|
id = Int32.Parse (values [0]);
|
||||||
|
timestamp = DateTime.Parse (values [1]);
|
||||||
|
msg = values [2];
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Bad example (validation):
|
||||||
|
<code>
|
||||||
|
bool ParseLine (string line)
|
||||||
|
{
|
||||||
|
string values = line.Split (',');
|
||||||
|
if (values.Length == 3) {
|
||||||
|
try {
|
||||||
|
id = Int32.Parse (values [0]);
|
||||||
|
timestamp = DateTime.Parse (values [1]);
|
||||||
|
msg = values [2];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
// catching all exception is bad
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
bool ParseLine (string line)
|
||||||
|
{
|
||||||
|
string values = line.Split (',');
|
||||||
|
if (values.Length == 3) {
|
||||||
|
if (!Int32.TryParse (values [0], out id))
|
||||||
|
return false;
|
||||||
|
if (!DateTime.TryParse (values [1], out timestamp))
|
||||||
|
return false;
|
||||||
|
msg = values [2];
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.8</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.BadPractice.PreferSafeHandleRule">
|
||||||
|
<summary>
|
||||||
|
In general it is best to interop with native code using
|
||||||
|
<c>System.Runtime.InteropServices.SafeHandle</c> instead of
|
||||||
|
<c>System.IntPtr</c> or <c>System.UIntPtr</c> because:
|
||||||
|
<list type="bullet"><item><description>SafeHandles are type safe.</description></item><item><description>SafeHandles are guaranteed to be disposed of during
|
||||||
|
exceptional conditions like a thread aborting unexpectedly or a stack
|
||||||
|
overflow.</description></item><item><description>SafeHandles are not vulnerable to reycle attacks.</description></item><item><description>You don't need to write a finalizer which can be tricky
|
||||||
|
to do because they execute within their own thread, may execute on
|
||||||
|
partially constructed objects, and normally tear down the application
|
||||||
|
if you allow an exception to escape from them.</description></item></list></summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Security;
|
||||||
|
using System.Security.Permissions;
|
||||||
|
// If cleaning up the native resource in a timely manner is important you can
|
||||||
|
// implement IDisposable.
|
||||||
|
public sealed class Database {
|
||||||
|
~Database ()
|
||||||
|
{
|
||||||
|
// This will execute even if the ctor throws so it is important to check
|
||||||
|
// to see if the fields are initialized.
|
||||||
|
if (m_database != IntPtr.Zero) {
|
||||||
|
NativeMethods.sqlite3_close (m_database);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public Database (string path)
|
||||||
|
{
|
||||||
|
NativeMethods.OpenFlags flags = NativeMethods.OpenFlags.READWRITE | NativeMethods.OpenFlags.CREATE;
|
||||||
|
int err = NativeMethods.sqlite3_open_v2 (path, out m_database, flags, IntPtr.Zero);
|
||||||
|
// handle errors
|
||||||
|
}
|
||||||
|
// exec and query methods would go here
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
private static class NativeMethods {
|
||||||
|
[Flags]
|
||||||
|
public enum OpenFlags : int {
|
||||||
|
READONLY = 0x00000001,
|
||||||
|
READWRITE = 0x00000002,
|
||||||
|
CREATE = 0x00000004,
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
[DllImport ("sqlite3")]
|
||||||
|
public static extern int sqlite3_close (IntPtr db);
|
||||||
|
[DllImport ("sqlite3")]
|
||||||
|
public static extern int sqlite3_open_v2 (string fileName, out IntPtr db, OpenFlags flags, IntPtr module);
|
||||||
|
}
|
||||||
|
private IntPtr m_database;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
using System.Runtime.ConstrainedExecution;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Security;
|
||||||
|
using System.Security.Permissions;
|
||||||
|
// If cleaning up the native resource in a timely manner is important you can
|
||||||
|
// implement IDisposable, but you do not need to implement a finalizer because
|
||||||
|
// SafeHandle will take care of the cleanup.
|
||||||
|
internal sealed class Database {
|
||||||
|
public Database (string path)
|
||||||
|
{
|
||||||
|
NativeMethods.OpenFlags flags = NativeMethods.OpenFlags.READWRITE | NativeMethods.OpenFlags.CREATE;
|
||||||
|
m_database = new SqlitePtr (path, flags);
|
||||||
|
}
|
||||||
|
// exec and query methods would go here
|
||||||
|
// This corresponds to a native sqlite3*.
|
||||||
|
[SecurityPermission (SecurityAction.InheritanceDemand, UnmanagedCode = true)]
|
||||||
|
[SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
|
||||||
|
private sealed class SqlitePtr : SafeHandle {
|
||||||
|
public SqlitePtr (string path, NativeMethods.OpenFlags flags) : base (IntPtr.Zero, true)
|
||||||
|
{
|
||||||
|
int err = NativeMethods.sqlite3_open_v2 (path, out handle, flags, IntPtr.Zero);
|
||||||
|
// handle errors
|
||||||
|
}
|
||||||
|
public override bool IsInvalid {
|
||||||
|
get {
|
||||||
|
return (handle == IntPtr.Zero);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// This will not be called if the handle is invalid. Note that this method should not throw.
|
||||||
|
[ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
|
||||||
|
protected override bool ReleaseHandle ()
|
||||||
|
{
|
||||||
|
NativeMethods.sqlite3_close (this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
private static class NativeMethods {
|
||||||
|
[Flags]
|
||||||
|
public enum OpenFlags : int {
|
||||||
|
READONLY = 0x00000001,
|
||||||
|
READWRITE = 0x00000002,
|
||||||
|
CREATE = 0x00000004,
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
[DllImport ("sqlite3")]
|
||||||
|
public static extern int sqlite3_close (SqlitePtr db);
|
||||||
|
// Open must take an IntPtr but all other methods take a type safe SqlitePtr.
|
||||||
|
[DllImport ("sqlite3")]
|
||||||
|
public static extern int sqlite3_open_v2 (string fileName, out IntPtr db, OpenFlags flags, IntPtr module);
|
||||||
|
}
|
||||||
|
private SqlitePtr m_database;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.6</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.BadPractice.ReplaceIncompleteOddnessCheckRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for problematic oddness checks. Often this is done by comparing
|
||||||
|
a value modulo two (% 2) with one (1). However this will not work if the value is
|
||||||
|
negative because negative one will be returned. A better (and faster) approach is
|
||||||
|
to check the least significant bit of the integer.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public bool IsOdd (int x)
|
||||||
|
{
|
||||||
|
// (x % 2) won't work for negative numbers (it returns -1)
|
||||||
|
return ((x % 2) == 1);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public bool IsOdd (int x)
|
||||||
|
{
|
||||||
|
return ((x % 2) != 0);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (faster):
|
||||||
|
<code>
|
||||||
|
public bool IsOdd (int x)
|
||||||
|
{
|
||||||
|
return ((x & 1) == 1);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.BadPractice.ToStringShouldNotReturnNullRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for overridden <c>ToString()</c> methods which return <c>null</c>.
|
||||||
|
An appropriately descriptive string, or <c>string.Empty</c>, should be returned
|
||||||
|
instead in order to make the value more useful (especially in debugging).
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public override string ToString ()
|
||||||
|
{
|
||||||
|
return (count == 0) ? null : count.ToString ();
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public override string ToString ()
|
||||||
|
{
|
||||||
|
return count.ToString ();
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>Before Gendarme 2.4 this rule was named ToStringReturnsNull.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.BadPractice.UseFileOpenOnlyWithFileAccessRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks that when file open method is called with FileMode parameter
|
||||||
|
it is also called with FileAccess (or FileSystemRights) parameter. It is needed
|
||||||
|
because default behaviour of file open methods when they are called only with
|
||||||
|
FileMode is to require read-write access while it is commonly expected that they
|
||||||
|
will require only read access.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public void OpenFile ()
|
||||||
|
{
|
||||||
|
FileStream f = File.Open ("Filename.ext", FileMode.Open);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public void OpenFile ()
|
||||||
|
{
|
||||||
|
FileStream f = File.Open ("Filename.ext", FileMode.Open, FileAccess.Read);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
|
</doc>
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -0,0 +1,555 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<doc>
|
||||||
|
<assembly>
|
||||||
|
<name>Gendarme.Rules.Concurrency</name>
|
||||||
|
</assembly>
|
||||||
|
<members>
|
||||||
|
<member name="T:Gendarme.Rules.Concurrency.DecorateThreadsRule">
|
||||||
|
<summary>
|
||||||
|
This rule is designed to help you precisely specify the threading semantics supported
|
||||||
|
by your code. This is valuable because it forces you to think clearly about the semantics
|
||||||
|
required of the code, the semantics are explicitly visible in the code, and the rule verifies
|
||||||
|
that the specification remains consistent.
|
||||||
|
In order to do this the rule relies on an attribute which allows you to declare that your
|
||||||
|
code can only run under the main thread, that it can run under an arbitrary thread,
|
||||||
|
that it can run under multiple threads if the execution is serialized, or that the code
|
||||||
|
is fully concurrent.
|
||||||
|
The rule enforces the following constraints:
|
||||||
|
<list><item>Thread entry points cannot be main thread.</item><item>MainThread code can call everything, AllowEveryCaller code can be called by
|
||||||
|
everything, SingleThread can call SingleThread/Serializable/Concurrent, and Serializable/
|
||||||
|
Concurrent can call Serializable/Concurrent.</item><item>Delegates must be able to call the methods they are bound to.</item><item>An override of a base method or an implementation of an interface method must
|
||||||
|
use the same threading model as the original method.</item><item>A delegate used with a threaded event must use the same threading model as the
|
||||||
|
event.</item><item>Serializable cannot be applied to static methods and static methods of serializeable
|
||||||
|
types do not inherit it from their types. (The rationale here is that there is normally nothing
|
||||||
|
that can be used to serialize access to static methods other than the type which is a bad
|
||||||
|
idea, see [http://bytes.com/groups/net-c/249277-dont-lock-type-objects]).</item></list>
|
||||||
|
When adding the attributes to a non-trivial amount of threaded code it seems best to focus
|
||||||
|
on one thread at a time so that it is easier to understand how the methods interact and which
|
||||||
|
threading model needs to be used by them. While doing this the defects for the other threads
|
||||||
|
can be temporarily suppressed using gendarme's --ignore switch.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
internal sealed class Wrapper : IDisposable
|
||||||
|
{
|
||||||
|
// Finalizers execute from a worker thread so the rule will complain
|
||||||
|
// if they are main thread.
|
||||||
|
~Wrapper ()
|
||||||
|
{
|
||||||
|
Dispose (false);
|
||||||
|
}
|
||||||
|
public void Dispose ()
|
||||||
|
{
|
||||||
|
Dispose (true);
|
||||||
|
GC.SuppressFinalize (this);
|
||||||
|
}
|
||||||
|
private void Dispose (bool disposing)
|
||||||
|
{
|
||||||
|
if (!Disposed) {
|
||||||
|
Disposed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private bool Disposed { get; set; }
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public enum ThreadModel {
|
||||||
|
// The code may run safely only under the main thread (this is the
|
||||||
|
// default for code in the assemblies being checked).
|
||||||
|
MainThread = 0x0000,
|
||||||
|
// The code may run under a single arbitrary thread.
|
||||||
|
SingleThread = 0x0001,
|
||||||
|
// The code may run under multiple threads, but only if the
|
||||||
|
// execution is serialized (e.g. by user level locking).
|
||||||
|
Serializable = 0x0002,
|
||||||
|
// The code may run under multiple threads concurrently without user
|
||||||
|
// locking (this is the default for code in the System/Mono namespaces).
|
||||||
|
Concurrent = 0x0003,
|
||||||
|
// Or this with the above for the rare cases where the code cannot be
|
||||||
|
// shown to be correct using a static analysis.
|
||||||
|
AllowEveryCaller = 0x0008,
|
||||||
|
}
|
||||||
|
// This is used to precisely specify the threading semantics of code. Note
|
||||||
|
// that Gendarme's DecorateThreadsRule will catch problematic code which
|
||||||
|
// uses these attributes (such as concurrent code calling main thread code).
|
||||||
|
[Serializable]
|
||||||
|
[AttributeUsage (AttributeTargets.Class | AttributeTargets.Struct |
|
||||||
|
AttributeTargets.Interface | AttributeTargets.Delegate |
|
||||||
|
AttributeTargets.Method | AttributeTargets.Event | AttributeTargets.Property,
|
||||||
|
AllowMultiple = false, Inherited = false)]
|
||||||
|
public sealed class ThreadModelAttribute : Attribute {
|
||||||
|
public ThreadModelAttribute (ThreadModel model)
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
public ThreadModel Model { get; set; }
|
||||||
|
}
|
||||||
|
internal sealed class Wrapper : IDisposable
|
||||||
|
{
|
||||||
|
[ThreadModel (ThreadModel.SingleThread)]
|
||||||
|
~Wrapper ()
|
||||||
|
{
|
||||||
|
Dispose (false);
|
||||||
|
}
|
||||||
|
public void Dispose ()
|
||||||
|
{
|
||||||
|
Dispose (true);
|
||||||
|
GC.SuppressFinalize (this);
|
||||||
|
}
|
||||||
|
// This is called from both the finalizer thread and the main thread
|
||||||
|
// so it must be decorated. But it only executes under one thread
|
||||||
|
// at a time so we can use SingleThread instead of Concurrent.
|
||||||
|
[ThreadModel (ThreadModel.SingleThread)]
|
||||||
|
private void Dispose (bool disposing)
|
||||||
|
{
|
||||||
|
if (!Disposed) {
|
||||||
|
Disposed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// This is called from a threaded method so it must also be
|
||||||
|
// threaded.
|
||||||
|
[ThreadModel (ThreadModel.SingleThread)]
|
||||||
|
private bool Disposed { get; set; }
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Concurrency.DoNotLockOnThisOrTypesRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks if you're using <c>lock</c> on the current instance (<c>this</c>) or
|
||||||
|
on a <c>Type</c>. This can cause
|
||||||
|
problems because anyone can acquire a lock on the instance or type. And if another
|
||||||
|
thread does acquire a lock then deadlocks become a very real possibility. The preferred way to
|
||||||
|
handle this is to create a private <c>System.Object</c> instance field and <c>lock</c> that. This
|
||||||
|
greatly reduces the scope of the code which may acquire the lock which makes it much easier
|
||||||
|
to ensure that the locking is done correctly.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example (this):
|
||||||
|
<code>
|
||||||
|
public void MethodLockingOnThis ()
|
||||||
|
{
|
||||||
|
lock (this) {
|
||||||
|
producer++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Bad example (type):
|
||||||
|
<code>
|
||||||
|
public void MethodLockingOnType ()
|
||||||
|
{
|
||||||
|
lock (this.GetType ()) {
|
||||||
|
producer++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
class ClassWithALocker {
|
||||||
|
object locker = new object ();
|
||||||
|
int producer = 0;
|
||||||
|
public void MethodLockingLocker ()
|
||||||
|
{
|
||||||
|
lock (locker) {
|
||||||
|
producer++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Concurrency.DoNotLockOnWeakIdentityObjectsRule">
|
||||||
|
<summary>
|
||||||
|
This rule ensures there are no locks on objects with weak identity.
|
||||||
|
An object with weak identity is one that can be directly accessed across
|
||||||
|
different application domains. Because these objects can be accessed
|
||||||
|
by different application domains it is very difficult to ensure that the
|
||||||
|
locking is done correctly so problems such as deadlocks are much more likely.
|
||||||
|
The following types have a weak identities:
|
||||||
|
<list type="bullet"><item><description><c>System.MarshalByRefObject</c></description></item><item><description><c>System.OutOfMemoryException</c></description></item><item><description><c>System.Reflection.MemberInfo</c></description></item><item><description><c>System.Reflection.ParameterInfo</c></description></item><item><description><c>System.ExecutionEngineException</c></description></item><item><description><c>System.StackOverflowException</c></description></item><item><description><c>System.String</c></description></item><item><description><c>System.Threading.Thread</c></description></item></list></summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public void WeakIdLocked ()
|
||||||
|
{
|
||||||
|
lock ("CustomString") {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public void WeakIdNotLocked ()
|
||||||
|
{
|
||||||
|
Phone phone = new Phone ();
|
||||||
|
lock (phone) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Concurrency.DoNotUseMethodImplOptionsSynchronizedRule">
|
||||||
|
<summary>
|
||||||
|
This rule fires if a method is decorated with <c>[MethodImpl(MethodImplOptions.Synchronized)]</c>.
|
||||||
|
The runtime synchronizes those methods automatically using a <c>lock(this)</c> for
|
||||||
|
instance methods or a <c>lock(typeof(X))</c> for static methods. This can cause
|
||||||
|
problems because anyone can acquire a lock on the instance or type. And if another
|
||||||
|
thread does acquire a lock then deadlocks become a very real possibility. The preferred way to
|
||||||
|
handle this is to create a private <c>System.Object</c> instance field and <c>lock</c> that. This
|
||||||
|
greatly reduces the scope of the code which may acquire the lock which makes it much easier
|
||||||
|
to ensure that the locking is done correctly.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[MethodImpl (MethodImplOptions.Synchronized)]
|
||||||
|
public void SychronizedMethod ()
|
||||||
|
{
|
||||||
|
producer++;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public class ClassWithALocker {
|
||||||
|
object locker = new object ();
|
||||||
|
int producer = 0;
|
||||||
|
public void MethodLockingLocker ()
|
||||||
|
{
|
||||||
|
lock (locker) {
|
||||||
|
producer++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Concurrency.DoNotUseThreadStaticWithInstanceFieldsRule">
|
||||||
|
<summary>
|
||||||
|
This rule will fire if an instance field is decorated with a <c>[ThreadStatic]</c> attribute.
|
||||||
|
This is an error because the attribute will only work with static fields.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
// the field isn't static so this will do nothing
|
||||||
|
[ThreadStatic]
|
||||||
|
private List<object> items;
|
||||||
|
public void Add (object item)
|
||||||
|
{
|
||||||
|
// If the field was thread safe this would ensure that each thread had
|
||||||
|
// its own copy of the list.
|
||||||
|
if (items == null) {
|
||||||
|
items = new List<object> ();
|
||||||
|
}
|
||||||
|
items.Add (item);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
private List<object> items = new List<object> ();
|
||||||
|
private object mutex = new object ();
|
||||||
|
// Typically some form of locking such as the code below is used to
|
||||||
|
// serialize access to instance fields. However you can also use
|
||||||
|
// Threading.Thread.Thread::AllocateNamedDataSlot or AllocateDataSlot.
|
||||||
|
public void Add (object item)
|
||||||
|
{
|
||||||
|
lock (mutex) {
|
||||||
|
items.Add (item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.6</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Concurrency.DoNotUseLockedRegionOutsideMethodRule">
|
||||||
|
<summary>
|
||||||
|
This rule will fire if a method calls <c>System.Threading.Monitor.Enter</c>,
|
||||||
|
but not <c>System.Threading.Monitor.Exit</c>. This is a bad idea for public
|
||||||
|
methods because the callers must (indirectly) manage a lock which they do not
|
||||||
|
own. This increases the potential for problems such as dead locks because
|
||||||
|
locking/unlocking may not be done together, the callers must do the unlocking
|
||||||
|
even in the presence of exceptions, and it may not be completely clear that
|
||||||
|
the public method is acquiring a lock without releasing it.
|
||||||
|
This is less of a problem for private methods because the lock is managed by
|
||||||
|
code that owns the lock. So, it's relatively easy to analyze the class to ensure
|
||||||
|
that the lock is locked and unlocked correctly and that any invariants are
|
||||||
|
preserved when the lock is acquired and after it is released. However it is
|
||||||
|
usually simpler and more maintainable if methods unlock whatever they lock.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
class BadExample {
|
||||||
|
int producer = 0;
|
||||||
|
object lock = new object();
|
||||||
|
// This class is meant to be thread safe, but in the interests of
|
||||||
|
// performance it requires clients to manage its lock. This allows
|
||||||
|
// clients to grab the lock, batch up edits, and release the lock
|
||||||
|
// when they are done. But this means that the clients must
|
||||||
|
// now (implicitly) manage the lock which is problematic, especially
|
||||||
|
// if this object is shared across threads.
|
||||||
|
public void BeginEdits ()
|
||||||
|
{
|
||||||
|
Monitor.Enter (lock);
|
||||||
|
}
|
||||||
|
public void AddProducer ()
|
||||||
|
{
|
||||||
|
// Real code would either assert or throw if the lock is not held.
|
||||||
|
producer++;
|
||||||
|
}
|
||||||
|
public void EndEdits ()
|
||||||
|
{
|
||||||
|
Monitor.Exit (lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
class GoodExample {
|
||||||
|
int producer = 0;
|
||||||
|
object mutex = new object();
|
||||||
|
public void AddProducer ()
|
||||||
|
{
|
||||||
|
// We need a try block in case the assembly is compiled with
|
||||||
|
// checked arithmetic.
|
||||||
|
Monitor.Enter (mutex);
|
||||||
|
try {
|
||||||
|
producer++;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
Monitor.Exit (mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void AddProducer2 ()
|
||||||
|
{
|
||||||
|
// Same as the above, but with C# sugar.
|
||||||
|
lock (mutex) {
|
||||||
|
producer++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Concurrency.DoubleCheckLockingRule">
|
||||||
|
<summary>
|
||||||
|
This rule is used to check for the double-check pattern, often used when implementing
|
||||||
|
the singleton pattern (1), and warns of potential incorrect usage.
|
||||||
|
The original CLR (1.x) could not guarantee that a double-check would work correctly
|
||||||
|
in multithreaded applications. However the technique does work on the x86 architecture,
|
||||||
|
the most common architecture, so the problem is seldom seen (e.g. IA64).
|
||||||
|
The CLR 2 and later introduce a strong memory model (2) where a double check for a
|
||||||
|
<c>lock</c> is correct (as long as you assign to a <c>volatile</c> variable). This
|
||||||
|
rule won't report a defect for assemblies targetting the 2.0 (and later) runtime.
|
||||||
|
<list><item><term>1. Implementing Singleton in C#</term><description>
|
||||||
|
http://msdn.microsoft.com/en-us/library/ms998558.aspx</description></item><item><term>2. Understand the Impact of Low-Lock Techniques in Multithreaded Apps</term><description>http://msdn.microsoft.com/en-ca/magazine/cc163715.aspx#S5</description></item></list></summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public class Singleton {
|
||||||
|
private static Singleton instance;
|
||||||
|
private static object syncRoot = new object ();
|
||||||
|
public static Singleton Instance {
|
||||||
|
get {
|
||||||
|
if (instance == null) {
|
||||||
|
lock (syncRoot) {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = new Singleton ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (for 1.x code avoid using double check):
|
||||||
|
<code>
|
||||||
|
public class Singleton {
|
||||||
|
private static Singleton instance;
|
||||||
|
private static object syncRoot = new object ();
|
||||||
|
public static Singleton Instance {
|
||||||
|
get {
|
||||||
|
// do not check instance before the lock
|
||||||
|
// this will work on all CLRs but will affect
|
||||||
|
// performance since the lock is always acquired
|
||||||
|
lock (syncRoot) {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = new Singleton ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (for 2.x and later):
|
||||||
|
<code>
|
||||||
|
public class Singleton {
|
||||||
|
// by using 'volatile' the double check will work under CLR 2.x
|
||||||
|
private static volatile Singleton instance;
|
||||||
|
private static object syncRoot = new object ();
|
||||||
|
public static Singleton Instance {
|
||||||
|
get {
|
||||||
|
if (instance == null) {
|
||||||
|
lock (syncRoot) {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = new Singleton ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Concurrency.NonConstantStaticFieldsShouldNotBeVisibleRule">
|
||||||
|
<summary>
|
||||||
|
This rule warns if a non-constant public static field is found.
|
||||||
|
In a multi-threaded environment access to those fields must be synchronized.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
class HasPublicStaticField {
|
||||||
|
public static ComplexObject Field;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
class FieldIsReadonly {
|
||||||
|
public readonly static ComplexObject Field = new ComplexObject();
|
||||||
|
}
|
||||||
|
</code><code>
|
||||||
|
class UseThreadStatic {
|
||||||
|
[ThreadStatic]
|
||||||
|
public static ComplexObject Field;
|
||||||
|
public static InitializeThread ()
|
||||||
|
{
|
||||||
|
if (Field == null)
|
||||||
|
Field = new ComplexObject ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Concurrency.ProtectCallToEventDelegatesRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks that event invocations are safely implemented. In particular,
|
||||||
|
the event must be copied into a local to avoid race conditions and it must be
|
||||||
|
checked for null before it is used (events will normally be null until a delegate is added
|
||||||
|
to them).
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example (no check):
|
||||||
|
<code>
|
||||||
|
public event EventHandler Loading;
|
||||||
|
protected void OnLoading (EventArgs e)
|
||||||
|
{
|
||||||
|
// Loading field could be null, throwing a NullReferenceException
|
||||||
|
Loading (this, e);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Bad example (race condition):
|
||||||
|
<code>
|
||||||
|
public event EventHandler Loading;
|
||||||
|
protected void OnLoading (EventArgs e)
|
||||||
|
{
|
||||||
|
// Loading could be non-null here
|
||||||
|
if (Loading != null) {
|
||||||
|
// but be null once we get here :(
|
||||||
|
Loading (this, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public event EventHandler Loading;
|
||||||
|
protected void OnLoading (EventArgs e)
|
||||||
|
{
|
||||||
|
EventHandler handler = Loading;
|
||||||
|
// handler is either null or non-null
|
||||||
|
if (handler != null) {
|
||||||
|
// and won't change (i.e. safe from a NullReferenceException)
|
||||||
|
handler (this, e);
|
||||||
|
// however it is still possible, like the original code, that
|
||||||
|
// the Loading method will be removed before, or during its
|
||||||
|
// execution. Your code should be safe against such occurance.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Concurrency.ReviewLockUsedOnlyForOperationsOnVariablesRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks if a lock is used only to perform operations on locals
|
||||||
|
or fields.
|
||||||
|
If the only purpose of that critical section is to make sure the variables
|
||||||
|
are modified atomatically then the methods provided by
|
||||||
|
System.Threading.Interlocked class will be more efficient.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
lock (_lockObject) {
|
||||||
|
_counter++;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
Interlocked.Increment(_counter);
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
lock (_lockObject) {
|
||||||
|
_someSharedObject = anotherObject;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
Interlocked.Exchange(_someSharedObject, anotherObject);
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Concurrency.WriteStaticFieldFromInstanceMethodRule">
|
||||||
|
<summary>
|
||||||
|
This rule is used to check for instance methods which write values to static fields.
|
||||||
|
This may cause problems if multiple instances of the type exist and are used in
|
||||||
|
multithreaded applications.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
static int default_value;
|
||||||
|
public int Value {
|
||||||
|
get {
|
||||||
|
if (default_value == 0) {
|
||||||
|
default_value = -1;
|
||||||
|
}
|
||||||
|
return (value > default_value) ? value : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
static int default_value = -1;
|
||||||
|
public int Value {
|
||||||
|
get {
|
||||||
|
return (value > default_value) ? value : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
|
</doc>
|
Двоичный файл не отображается.
Двоичный файл не отображается.
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -0,0 +1,243 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<doc>
|
||||||
|
<assembly>
|
||||||
|
<name>Gendarme.Rules.Design.Generic</name>
|
||||||
|
</assembly>
|
||||||
|
<members>
|
||||||
|
<member name="T:Gendarme.Rules.Design.Generic.AvoidDeclaringCustomDelegatesRule">
|
||||||
|
<summary>
|
||||||
|
This rule will fire if custom delegates are defined when either pre-defined <code>System.Action</code>,
|
||||||
|
<code>Action<T[,...]></code> or <code>Func<[Tx,...]TResult></code> could have been used.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example (without return value):
|
||||||
|
<code>
|
||||||
|
delegate void MyCustomDelegate (int a);
|
||||||
|
private MyCustomDelegate custom_delegate;
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (without return value):
|
||||||
|
<code>
|
||||||
|
private Action<int> action_delegate;
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Bad example (with return value):
|
||||||
|
<code>
|
||||||
|
delegate int MyCustomDelegate (int a, string s);
|
||||||
|
private MyCustomDelegate custom_delegate;
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (with return value):
|
||||||
|
<code>
|
||||||
|
private Func<int,string,int> func_delegate;
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule applies only to assemblies targeting .NET 2.0 and later.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Design.Generic.AvoidExcessiveParametersOnGenericTypesRule">
|
||||||
|
<summary>
|
||||||
|
A visible type should not have more than two generic parameters. This makes it
|
||||||
|
hard for consumers to remember what each parameter is required for.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public class BadClass<A, B, C> {
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public class GoodClass<A, B> {
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule applies only to assemblies targeting .NET 2.0 and later.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Design.Generic.AvoidMethodWithUnusedGenericTypeRule">
|
||||||
|
<summary>
|
||||||
|
This method will fire if a generic method does not use all of its generic type parameters
|
||||||
|
in the formal parameter list. This usually means that either the type parameter is not used at
|
||||||
|
all in which case it should be removed or that it's used only for the return type which
|
||||||
|
is problematic because that prevents the compiler from inferring the generic type
|
||||||
|
when the method is called which is confusing to many developers.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public class Bad {
|
||||||
|
public string ToString<T> ()
|
||||||
|
{
|
||||||
|
return typeof (T).ToString ();
|
||||||
|
}
|
||||||
|
static void Main ()
|
||||||
|
{
|
||||||
|
// the compiler can't infer int so we need to supply it ourselves
|
||||||
|
Console.WriteLine (ToString<int> ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public class Good {
|
||||||
|
public string ToString<T> (T obj)
|
||||||
|
{
|
||||||
|
return obj.GetType ().ToString ();
|
||||||
|
}
|
||||||
|
static void Main ()
|
||||||
|
{
|
||||||
|
Console.WriteLine (ToString (2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule applies only to assemblies targeting .NET 2.0 and later.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Design.Generic.DoNotDeclareStaticMembersOnGenericTypesRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for generic types that contain static members. Such members requires the type argument
|
||||||
|
to be specified when consumed, leading to harder to use or confusing API.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public class BadClass<T> {
|
||||||
|
public static string Member () {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public class GoodClass<T> {
|
||||||
|
public string Member () {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule applies only to assemblies targeting .NET 2.0 and later.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Design.Generic.DoNotExposeGenericListsRule">
|
||||||
|
<summary>
|
||||||
|
A type has an externally visible member that is, returns or has a signature containing a
|
||||||
|
<c>System.Collections.Generic.List<T></c>.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public class BadClass {
|
||||||
|
public List<string> member { get; set; };
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public class GoodClass {
|
||||||
|
public Collection<string> member { get; set; };
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule applies only to assemblies targeting .NET 2.0 and later.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Design.Generic.DoNotExposeNestedGenericSignaturesRule">
|
||||||
|
<summary>
|
||||||
|
This rule will fire if an externally visible method has a parameter or return type
|
||||||
|
whose type is a generic type which contains a generic type. For example,
|
||||||
|
<c>List<List<int>></c>. Such types are hard to construct and should
|
||||||
|
be avoided because simpler alternatives generally exist.
|
||||||
|
Since some language, like C#, have direct support for nullable types, i.e.
|
||||||
|
<c>System.Nullable<T></c> this specific case is ignored by the rule.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public class Generic<T> {
|
||||||
|
public void Process (KeyValuePair<T, ICollection<int>> value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public class Generic<T> {
|
||||||
|
public void Process (KeyValuePair<T, int[]> value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule applies only to assemblies targeting .NET 2.0 and later.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Design.Generic.ImplementGenericCollectionInterfacesRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for types which implement the non-generic <code>System.IEnumerable</code> interface but
|
||||||
|
not the <code>System.IEnumerable<T></code> interface. Implementing the generic version
|
||||||
|
of <code>System.IEnumerable</code> avoids casts, and possibly boxing, when iterating the collection.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public class IntEnumerable : IEnumerable {
|
||||||
|
public IEnumerator GetEnumerator ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public class IntEnumerable : IEnumerable<int> {
|
||||||
|
public IEnumerator<int> GetEnumerator ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
IEnumerator IEnumerable.GetEnumerator ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule applies only to assemblies targeting .NET 2.0 and later.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Design.Generic.PreferGenericsOverRefObjectRule">
|
||||||
|
<summary>
|
||||||
|
This rule fires if a method has a reference argument (<c>ref</c> or
|
||||||
|
<c>out</c> in C#) to <c>System.Object</c>. These methods can generally be
|
||||||
|
rewritten in .NET 2.0 using generics which provides type safety, eliminates
|
||||||
|
casts, and makes the API easier to consume.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
// common before 2.0 but we can do better now
|
||||||
|
public bool TryGetValue (string key, ref object value)
|
||||||
|
{
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public bool TryGetValue<T> (string key, ref T value)
|
||||||
|
{
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule applies only to assemblies targeting .NET 2.0 and later.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Design.Generic.UseGenericEventHandlerRule">
|
||||||
|
<summary>
|
||||||
|
This rule fires if an assembly defines a delegate which can be
|
||||||
|
replaced by <c>System.EventHandler<TEventArgs></c>.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public delegate void AuthenticityHandler (object sender, AuthenticityEventArgs e);
|
||||||
|
public event AuthenticityHandler CheckingAuthenticity;
|
||||||
|
public event AuthenticityHandler CheckedAuthenticity;
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public event EventHandler<AuthenticityEventArgs> CheckingAuthenticity;
|
||||||
|
public event EventHandler<AuthenticityEventArgs> CheckedAuthenticity;
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule applies only to assemblies targeting .NET 2.0 and later.</remarks>
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
|
</doc>
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<doc>
|
||||||
|
<assembly>
|
||||||
|
<name>Gendarme.Rules.Design.Linq</name>
|
||||||
|
</assembly>
|
||||||
|
<members>
|
||||||
|
<member name="T:Gendarme.Rules.Design.Linq.AvoidExtensionMethodOnSystemObjectRule">
|
||||||
|
<summary>
|
||||||
|
Extension methods should not be used to extend <c>System.Object</c>.
|
||||||
|
Such extension methods cannot be consumed by some languages, like VB.NET,
|
||||||
|
which use late-binding on <c>System.Object</c> instances.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public static class Extensions {
|
||||||
|
public static string ToDebugString (this object self)
|
||||||
|
{
|
||||||
|
return String.Format ("'{0}', type '{1}', hashcode: {2}",
|
||||||
|
self.ToString (), self.GetType (), self.GetHashCode ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public static class Extensions {
|
||||||
|
public static string ToDebugString (this DateTime self)
|
||||||
|
{
|
||||||
|
return String.Format ("'{0}', type '{1}', hashcode: {2}",
|
||||||
|
self.ToString (), self.GetType (), self.GetHashCode ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.2</remarks>
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
|
</doc>
|
Двоичный файл не отображается.
Двоичный файл не отображается.
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -0,0 +1,442 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<doc>
|
||||||
|
<assembly>
|
||||||
|
<name>Gendarme.Rules.Exceptions</name>
|
||||||
|
</assembly>
|
||||||
|
<members>
|
||||||
|
<member name="T:Gendarme.Rules.Exceptions.AvoidArgumentExceptionDefaultConstructorRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks that every <c>System.ArgumentException</c>,
|
||||||
|
<c>System.ArgumentNullException</c>, <c>System.ArgumentOutOfRangeException</c>, or
|
||||||
|
<c>System.DuplicateWaitObjectException</c> exception created is provided with some
|
||||||
|
useful information about the exception being thrown, minimally the parameter name.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public void Add (object key, object value)
|
||||||
|
{
|
||||||
|
if ((obj == null) || (key == null)) {
|
||||||
|
throw new ArgumentNullException ();
|
||||||
|
}
|
||||||
|
Inner.Add (key, value);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public void Add (object key, object value)
|
||||||
|
{
|
||||||
|
if (key == null) {
|
||||||
|
throw new ArgumentNullException ("key");
|
||||||
|
}
|
||||||
|
if (obj == value) {
|
||||||
|
throw new ArgumentNullException ("value");
|
||||||
|
}
|
||||||
|
Inner.Add (key, value);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Exceptions.AvoidThrowingBasicExceptionsRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for methods that create basic exceptions like <c>System.Exception</c>,
|
||||||
|
<c>System.ApplicationException</c> or <c>System.SystemException</c>. Those exceptions
|
||||||
|
do not provide enough information about the error to be helpful to the consumer
|
||||||
|
of the library.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public void Add (object obj)
|
||||||
|
{
|
||||||
|
if (obj == null) {
|
||||||
|
throw new Exception ();
|
||||||
|
}
|
||||||
|
Inner.Add (obj);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public void Add (object obj)
|
||||||
|
{
|
||||||
|
if (obj == null) {
|
||||||
|
throw new ArgumentNullException ("obj");
|
||||||
|
}
|
||||||
|
Inner.Add (obj);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Exceptions.DoNotDestroyStackTraceRule">
|
||||||
|
<summary>
|
||||||
|
This rule will fire if a catch handler throws the exception it caught. What it should
|
||||||
|
do instead is rethrow the original exception (e.g. use <c>throw</c> instead of
|
||||||
|
<c>throw ex</c>). This is helpful because rethrow preserves the stacktrace of the
|
||||||
|
original exception.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
try {
|
||||||
|
Int32.Parse ("Broken!");
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
Assert.IsNotNull (ex);
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
try {
|
||||||
|
Int32.Parse ("Broken!");
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
Assert.IsNotNull (ex);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>Prior to Gendarme 2.0 this rule was named DontDestroyStackTraceRule.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Exceptions.DoNotThrowInNonCatchClausesRule">
|
||||||
|
<summary>
|
||||||
|
This rule detects exceptions that are throw in <c>fault</c>, <c>filter</c> or
|
||||||
|
<c>finally</c> clauses. Such exceptions will make it much harder to debug your
|
||||||
|
applications since it will hide the original exception.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
int err = 0;
|
||||||
|
try {
|
||||||
|
err = Initialize ();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
Cleanup ();
|
||||||
|
if (err != 0)
|
||||||
|
throw new NotSupportedException ();
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
try {
|
||||||
|
if (Initialize () != 0)
|
||||||
|
throw new NotSupportedException ();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
Cleanup ();
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Exceptions.DoNotThrowInUnexpectedLocationRule">
|
||||||
|
<summary>
|
||||||
|
There are a number of methods which have constraints on the exceptions
|
||||||
|
which they may throw. This rule checks the following methods:
|
||||||
|
<list type="bullet"><item><description>Property getters - properties should work very much
|
||||||
|
like fields: they should execute very quickly and, in general, should
|
||||||
|
not throw exceptions. However they may throw System.InvalidOperationException,
|
||||||
|
System.NotSupportedException, or an exception derived from these.
|
||||||
|
Indexed getters may also throw System.ArgumentException or
|
||||||
|
System.Collections.Generic.KeyNotFoundException.</description></item><item><description>Event accessors - in general events should not throw
|
||||||
|
when adding or removing a handler. However they may throw
|
||||||
|
System.InvalidOperationException, System.NotSupportedException,
|
||||||
|
System.ArgumentException, or an exception derived from these.</description></item><item><description>Object.Equals and IEqualityComparer<T>.Equals - should
|
||||||
|
not throw. In particular they should do something sensible when passed
|
||||||
|
null arguments or unexpected types.</description></item><item><description>Object.GetHashCode - should not throw or the object
|
||||||
|
will not work properly with dictionaries and hash sets.</description></item><item><description>IEqualityComparer<T>.GetHashCode - may throw
|
||||||
|
System.ArgumentException.</description></item><item><description>Object.ToString - these are called by the debugger to display
|
||||||
|
objects and are also often used with printf style debugging so they should
|
||||||
|
not change the object's state and should not throw.</description></item><item><description>static constructors - should very rarely throw. If they
|
||||||
|
do throw then the type will not be useable within that application
|
||||||
|
domain.</description></item><item><description>finalizers - should not throw. If they do (as of .NET 2.0)
|
||||||
|
the process will be torn down.</description></item><item><description>IDisposable.Dispose - should not throw. If they do
|
||||||
|
it's much harder to guarantee that objects clean up properly.</description></item><item><description>Dispose (bool) - should not throw because that makes
|
||||||
|
it very difficult to clean up objects and because they are often
|
||||||
|
called from a finalizer.</description></item><item><description>operator== and operator!= - should not throw. In particular
|
||||||
|
they should do something sensible when passed null arguments or
|
||||||
|
unexpected types.</description></item><item><description>implicit cast operators - should not throw. These methods
|
||||||
|
are called implicitly so it tends to be quite surprising if they throw
|
||||||
|
exceptions.</description></item><item><description><c>TryParse</c> methods - should not throw. These methods
|
||||||
|
are designed to be executed without having to catch multiple exceptions
|
||||||
|
(unlike the <c>Parse</c> methods).</description></item></list>
|
||||||
|
Note that the rule does not complain if a method throws
|
||||||
|
System.NotImplementedException because
|
||||||
|
DoNotForgetNotImplementedMethodsRule will flag them. Also the rule
|
||||||
|
may fire with anonymous types with gmcs versions prior to 2.2, see
|
||||||
|
[https://bugzilla.novell.com/show_bug.cgi?id=462622] for more details.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public override bool Equals (object obj)
|
||||||
|
{
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Customer rhs = (Customer) obj; // throws if obj is not a Customer
|
||||||
|
return name == rhs.name;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public override bool Equals (object obj)
|
||||||
|
{
|
||||||
|
Customer rhs = obj as Customer;
|
||||||
|
if (rhs == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return name == rhs.name;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.4</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Exceptions.DoNotThrowReservedExceptionRule">
|
||||||
|
<summary>
|
||||||
|
This rule will fire if an <c>System.ExecutionEngineException</c>, <c>System.IndexOutOfRangeException</c>,
|
||||||
|
<c>NullReferenceException</c>, or <c>System.OutOfMemoryException</c> class is
|
||||||
|
instantiated. These exceptions are for use by the runtime and should not be thrown by
|
||||||
|
user code.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public void Add (object obj)
|
||||||
|
{
|
||||||
|
if (obj == null) {
|
||||||
|
throw new NullReferenceException ("obj");
|
||||||
|
}
|
||||||
|
Inner.Add (obj);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public void Add (object obj)
|
||||||
|
{
|
||||||
|
if (obj == null) {
|
||||||
|
throw new ArgumentNullException ("obj");
|
||||||
|
}
|
||||||
|
Inner.Add (obj);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Exceptions.DoNotSwallowErrorsCatchingNonSpecificExceptionsRule">
|
||||||
|
<summary>
|
||||||
|
This rule will fire if a catch block catches <c>System.Exception</c> or
|
||||||
|
<c>System.SystemException</c> but does not rethrow the original
|
||||||
|
exception. This is problematic because you don't know what went wrong
|
||||||
|
so it's difficult to know that the error was handled correctly. It is better
|
||||||
|
to catch a more specific set of exceptions so that you do know what went
|
||||||
|
wrong and do know that it is handled correctly.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
try {
|
||||||
|
File.Open ("foo.txt", FileMode.Open);
|
||||||
|
}
|
||||||
|
catch (Exception) {
|
||||||
|
//Ooops what's failed ??? UnauthorizedException, FileNotFoundException ???
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (catch a specific exception):
|
||||||
|
<code>
|
||||||
|
try {
|
||||||
|
File.Open ("foo.txt", FileMode.Open);
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException exception) {
|
||||||
|
//I know that the system can't find the file.
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (catch all and rethrow):
|
||||||
|
<code>
|
||||||
|
try {
|
||||||
|
File.Open ("foo.txt", FileMode.Open);
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Console.WriteLine ("An error has happened.");
|
||||||
|
throw; // You don't swallow the error, because you rethrow the original exception.
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>Prior to Gendarme 2.0 this rule was named DontSwallowErrorsCatchingNonspecificExceptionsRule.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Exceptions.ExceptionShouldBeVisibleRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for non-visible exceptions which derive directly from
|
||||||
|
the most basic exceptions: <c>System.Exception</c>, <c>System.ApplicationException</c>
|
||||||
|
or <c>System.SystemException</c>. Those basic exceptions, being visible, will be the
|
||||||
|
only information available to the API consumer - but do not contain enough data to be
|
||||||
|
useful.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
internal class GeneralException : Exception {
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (visibility):
|
||||||
|
<code>
|
||||||
|
public class GeneralException : Exception {
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (base class):
|
||||||
|
<code>
|
||||||
|
internal class GeneralException : ArgumentException {
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Exceptions.InstantiateArgumentExceptionCorrectlyRule">
|
||||||
|
<summary>
|
||||||
|
This rule will fire if the arguments to the <c>System.ArgumentException</c>,
|
||||||
|
<c>System.ArgumentNullException</c>, <c>System.ArgumentOutOfRangeException</c>,
|
||||||
|
and <c>System.DuplicateWaitObjectException</c> constructors are used incorrectly.
|
||||||
|
This is a common mistake because the position of the <c>parameterName</c> argument
|
||||||
|
is not consistent across these types.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public void Show (string s)
|
||||||
|
{
|
||||||
|
if (s == null) {
|
||||||
|
// the first argument should be the parameter name
|
||||||
|
throw new ArgumentNullException ("string is null", "s");
|
||||||
|
}
|
||||||
|
if (s.Length == 0) {
|
||||||
|
// the second argument should be the parameter name
|
||||||
|
return new ArgumentException ("s", "string is empty");
|
||||||
|
}
|
||||||
|
Console.WriteLine (s);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public void Show (string s)
|
||||||
|
{
|
||||||
|
if (s == null) {
|
||||||
|
throw new ArgumentNullException ("s", "string is null");
|
||||||
|
}
|
||||||
|
if (s.Length == 0) {
|
||||||
|
return new ArgumentException ("string is empty", "s");
|
||||||
|
}
|
||||||
|
Console.WriteLine (s);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.2</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Exceptions.MissingExceptionConstructorsRule">
|
||||||
|
<summary>
|
||||||
|
This rule will fire if an exception class is missing one or more of the following
|
||||||
|
constructors:
|
||||||
|
<list><item><description><c>public E ()</c> is required for XML serialization. Public access is required
|
||||||
|
in case the assembly uses CAS to prevent reflection on non-public members.</description></item><item><description><c>public E (string message)</c> is a .NET convention.</description></item><item><description><c>public E (string message, ..., Exception inner)</c> is a .NET convention.</description></item><item><description><c>(non)public E (SerializationInfo info, StreamingContext context)</c> is required for binary serialization.</description></item></list></summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public class GeneralException : Exception {
|
||||||
|
// access should be public
|
||||||
|
private GeneralException ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public class GeneralException : Exception {
|
||||||
|
public GeneralException ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public GeneralException (string message) : base (message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public GeneralException (string message, Exception inner) : base (message, inner)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
protected GeneralException (SerializationInfo info, StreamingContext context) : base (info, context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Exceptions.UseObjectDisposedExceptionRule">
|
||||||
|
<summary>
|
||||||
|
It's usually a very bad idea to attempt to use an object after it has been
|
||||||
|
disposed. Doing so may lead to crashes in native code or any number of
|
||||||
|
other problems. In order to prevent this, and to report the problem in
|
||||||
|
a clear way, classes should throw System.ObjectDisposedException from
|
||||||
|
public methods if the object has been disposed.
|
||||||
|
Note that there are some methods which should not throw ObjectDisposedException.
|
||||||
|
This includes constructors, finalizers, Equals, GetHashCode, ToString, and Dispose.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
internal sealed class WriteStuff : IDisposable
|
||||||
|
{
|
||||||
|
public WriteStuff (TextWriter writer)
|
||||||
|
{
|
||||||
|
this.writer = writer;
|
||||||
|
}
|
||||||
|
// Objects are generally not in a useable state after being disposed so
|
||||||
|
// their public methods should throw ObjectDisposedException.
|
||||||
|
public void Write (string message)
|
||||||
|
{
|
||||||
|
writer.Write (message);
|
||||||
|
}
|
||||||
|
public void Dispose ()
|
||||||
|
{
|
||||||
|
if (!disposed) {
|
||||||
|
writer.Dispose ();
|
||||||
|
disposed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private bool disposed;
|
||||||
|
private TextWriter writer;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
internal sealed class WriteStuff : IDisposable
|
||||||
|
{
|
||||||
|
public WriteStuff (TextWriter writer)
|
||||||
|
{
|
||||||
|
this.writer = writer;
|
||||||
|
}
|
||||||
|
// In general all public methods should throw ObjectDisposedException
|
||||||
|
// if Dispose has been called.
|
||||||
|
public void Write (string message)
|
||||||
|
{
|
||||||
|
if (disposed) {
|
||||||
|
throw new ObjectDisposedException (GetType ().Name);
|
||||||
|
}
|
||||||
|
writer.Write (message);
|
||||||
|
}
|
||||||
|
public void Dispose ()
|
||||||
|
{
|
||||||
|
if (!disposed) {
|
||||||
|
writer.Dispose ();
|
||||||
|
disposed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private bool disposed;
|
||||||
|
private TextWriter writer;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.6</remarks>
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
|
</doc>
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -0,0 +1,138 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<doc>
|
||||||
|
<assembly>
|
||||||
|
<name>Gendarme.Rules.Gendarme</name>
|
||||||
|
</assembly>
|
||||||
|
<members>
|
||||||
|
<member name="T:Gendarme.Rules.Gendarme.DefectsMustBeReportedRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks if at least one method in types implementing
|
||||||
|
IRule is calling Runner.Report.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public class BadRule : Rule, ITypeRule
|
||||||
|
{
|
||||||
|
public RuleResult CheckType (TypeDefinition type)
|
||||||
|
{
|
||||||
|
return RuleResult.Failure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public class BadRule : Rule, ITypeRule
|
||||||
|
{
|
||||||
|
public RuleResult CheckType (TypeDefinition type)
|
||||||
|
{
|
||||||
|
Runner.Report(type, Severity.Low, Confidence.Total);
|
||||||
|
return RuleResult.Failure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>
|
||||||
|
This rule checks if Runner.Report is called directly anywhere in rules' methods but it does not
|
||||||
|
check if it being called in the base type or somewhere else, so some false positives are possible.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Gendarme.DoNotThrowExceptionRule">
|
||||||
|
<summary>
|
||||||
|
This rule finds Gendarme rules that throw exceptions because runner's behavior
|
||||||
|
in case of rule throwing an exception is undefined.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public class ExampleRule : Rule, IMethodRule {
|
||||||
|
public RuleResult CheckMethod (MethodDefinition method)
|
||||||
|
{
|
||||||
|
if (method == null)
|
||||||
|
throw new ArgumentNullException ("method");
|
||||||
|
// other rule logic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public class ExampleRule : Rule, IMethodRule {
|
||||||
|
public RuleResult CheckMethod (MethodDefinition method)
|
||||||
|
{
|
||||||
|
// method is not null by contract
|
||||||
|
return RuleResult.Success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Gendarme.MissingEngineDependencyRule">
|
||||||
|
<summary>
|
||||||
|
Rules should not use engines' features without subscribing to them
|
||||||
|
using EngineDependency attribute because it will not work unless
|
||||||
|
another rule has subscribed to the same engine.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
class BadRule : Rule, IMethodRule {
|
||||||
|
public RuleResult CheckMethod (MethodDefinition method)
|
||||||
|
{
|
||||||
|
if (!OpCodeBitmask.Calls.Intersect (OpCodeEngine.GetBitmask (method)))
|
||||||
|
return RuleResult.DoesNotApply;
|
||||||
|
// rule code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
[EngineDependency (typeof (OpCodeEngine))]
|
||||||
|
class BadRule : Rule, IMethodRule {
|
||||||
|
public RuleResult CheckMethod (MethodDefinition method)
|
||||||
|
{
|
||||||
|
if (!OpCodeBitmask.Calls.Intersect (OpCodeEngine.GetBitmask (method)))
|
||||||
|
return RuleResult.DoesNotApply;
|
||||||
|
// rule code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Gendarme.ReviewAttributesOnRulesRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks if attribute usage match the following rules:
|
||||||
|
<list><item><term>[Problem] and [Solution] attributes</term><description>should be used on rules only, every concrete rule must have both
|
||||||
|
attributes (or inherit them), and their arguments cannot be null or empty
|
||||||
|
</description></item><item><term>[FxCopCompatibility] attribute</term><description>should be used on rules only, its arguments cannot be null or empty,
|
||||||
|
and second argument should match this format: AB1234:FxCopRuleName</description></item><item><term>[EngineDependency] attribute</term><description>should be used on rules only, its argument cannot be null or empty,
|
||||||
|
and its argument should inherit from Gendarme.Framework.Engine</description></item><item><term>[DocumentationUri] attribute</term><description>should be used on rules only</description></item><item><term>[Description] and [DefaultValue] attributes</term><description>should be used on rules' public properties only,
|
||||||
|
Description attribute argument cannot be null or empty</description></item></list></summary>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Gendarme.UseCorrectSuffixRule">
|
||||||
|
<summary>
|
||||||
|
Types implementing IRule should have the "Rule" suffix, while other types
|
||||||
|
are not allowed to have this suffix.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example (rule type does not have a suffix):
|
||||||
|
<code>
|
||||||
|
public class ReviewSomething : Rule, IMethodRule {
|
||||||
|
// rule code
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Bad example (non-rule type has a suffix):
|
||||||
|
<code>
|
||||||
|
public class SomeRule {
|
||||||
|
// class code
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public class ReviewSomethingRule : Rule, IMethodRule {
|
||||||
|
// rule code
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
|
</doc>
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -0,0 +1,83 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<doc>
|
||||||
|
<assembly>
|
||||||
|
<name>Gendarme.Rules.Globalization</name>
|
||||||
|
</assembly>
|
||||||
|
<members>
|
||||||
|
<member name="T:Gendarme.Rules.Globalization.AvoidUnusedInternalResourceRule">
|
||||||
|
<summary>
|
||||||
|
This rule will check for internally visible resources (resx) which are never called.
|
||||||
|
You should remove unused internal resources to avoid useless translations.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Globalization.PreferIFormatProviderOverrideRule">
|
||||||
|
<summary>
|
||||||
|
This rule detects calls to method that could be changed to call an <c>override</c> accepting an
|
||||||
|
extra <c>System.IFormatProvider</c> or <c>System.Globalization.CultureInfo</c> parameter (the
|
||||||
|
later implements <c>System.IFormatProvider</c>).
|
||||||
|
Generally data displayed to the end user should be using
|
||||||
|
<c>System.Globalization.CultureInfo.CurrentCulture</c> while other data (e.g. used internally,
|
||||||
|
stored in files/databases) should use <c>System.Globalization.CultureInfo.InvariantCulture</c>.
|
||||||
|
The rule will ignore the following special methods:
|
||||||
|
<list><item><c>System.Activator.CreateInstance</c></item><item><c>System.Resources.ResourceManager.GetObject</c></item><item><c>System.Resources.ResourceManager.GetString</c></item></list></summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public bool Confirm (double amount)
|
||||||
|
{
|
||||||
|
string msg = String.Format ("Accept payment of {0} ?", amount);
|
||||||
|
Transaction.Log ("{0} {1}", DateTime.Now, amount);
|
||||||
|
return Prompt (msg);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public bool Confirm (double amount)
|
||||||
|
{
|
||||||
|
string msg = String.Format (CultureInfo.CurrentCulture, "Accept payment of {0} ?", amount);
|
||||||
|
Transaction.Log (CultureInfo.InvariantCulture, "{0} {1}", DateTime.Now, amount);
|
||||||
|
return Prompt (msg);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Globalization.PreferStringComparisonOverrideRule">
|
||||||
|
<summary>
|
||||||
|
This rule detects calls to method that could be changed to call an <c>override</c> accepting an
|
||||||
|
extra <c>System.StringComparison</c> parameter. Using the <c>override</c> makes the code easier
|
||||||
|
to maintain since it makes the intent clear on how the string needs to be compared.
|
||||||
|
It is even more important since the default string comparison rules have changed between
|
||||||
|
.NET 2.0 and .NET 4.0.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public bool Check (string name)
|
||||||
|
{
|
||||||
|
// it's not clear if the string comparison should be culture sensitive or not
|
||||||
|
return (String.Compare (name, "Software") == 0);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public bool Check (string name)
|
||||||
|
{
|
||||||
|
return (String.Compare (name, "Software", StringComparison.CurrentCulture) == 0);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Globalization.SatelliteResourceMismatchRule">
|
||||||
|
<summary>
|
||||||
|
A satellite assembly have a resource which does not match with a main assembly resource.
|
||||||
|
Either :
|
||||||
|
* The resource doesn't exist in the main assembly and should be removed from the satellite assembly.
|
||||||
|
* The resource is not of the same type in the main and satellite assembly. The satellite one should be fixed.
|
||||||
|
* The satellite string resource does not have the same string.Format parameters than the main assembly. The satellite one should be fixed.
|
||||||
|
</summary>
|
||||||
|
<remarks>
|
||||||
|
The satellites assemblies are searched in the subdirectories of the main assembly location.
|
||||||
|
</remarks>
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
|
</doc>
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -0,0 +1,378 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<doc>
|
||||||
|
<assembly>
|
||||||
|
<name>Gendarme.Rules.Interoperability.Com</name>
|
||||||
|
</assembly>
|
||||||
|
<members>
|
||||||
|
<member name="T:Gendarme.Rules.Interoperability.Com.AutoLayoutTypesShouldNotBeComVisibleRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for <c>[System.Runtime.InteropServices.ComVisible]</c> decorated value
|
||||||
|
types which have <c>[System.Runtime.InteropServices.StructLayout]</c> attribute set to
|
||||||
|
<c>System.Runtime.InteropServices.LayoutKind</c>.<c>Auto</c> because auto layout can
|
||||||
|
change between Mono and .NET or even between releases of the .NET/Mono frameworks.
|
||||||
|
Note that this does not affect <c>System.Enum</c>-based types.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[assembly: ComVisible (false)]
|
||||||
|
namespace InteropLibrary {
|
||||||
|
[ComVisible (true)]
|
||||||
|
[StructLayout (LayoutKind.Auto)]
|
||||||
|
public struct Good {
|
||||||
|
ushort a;
|
||||||
|
ushort b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example
|
||||||
|
<code>
|
||||||
|
[assembly: ComVisible (false)]
|
||||||
|
namespace InteropLibrary {
|
||||||
|
[ComVisible (true)]
|
||||||
|
[StructLayout (LayoutKind.Sequential)]
|
||||||
|
public struct Good {
|
||||||
|
ushort a;
|
||||||
|
ushort b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>
|
||||||
|
Rule applies only when the containing assembly has ComVisible attribute explicitly set to false
|
||||||
|
and the type has ComVisible attribute explicitly set to true.
|
||||||
|
</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Interoperability.Com.AvoidInt64ArgumentsInComVisibleMethodsRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks that ComVisible methods do not take System.Int64 arguments
|
||||||
|
because Visual Basic 6 clients do not support it.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[assembly: ComVisible (false)]
|
||||||
|
namespace InteropLibrary {
|
||||||
|
[ComVisible (true)]
|
||||||
|
public class Bad {
|
||||||
|
public void DoBadThings (long a)
|
||||||
|
{
|
||||||
|
// doing bad things
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (type changed):
|
||||||
|
<code>
|
||||||
|
[assembly: ComVisible (false)]
|
||||||
|
namespace InteropLibrary {
|
||||||
|
[ComVisible (true)]
|
||||||
|
public class Good {
|
||||||
|
public void DoGoodThings (int a)
|
||||||
|
{
|
||||||
|
// doing good things
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (method is not visible from COM):
|
||||||
|
<code>
|
||||||
|
[assembly: ComVisible (false)]
|
||||||
|
namespace InteropLibrary {
|
||||||
|
[ComVisible (true)]
|
||||||
|
public class Good {
|
||||||
|
[ComVisible (false)]
|
||||||
|
public void DoGoodThings (long a)
|
||||||
|
{
|
||||||
|
// doing good things
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>
|
||||||
|
Rule applies only when the containing assembly has ComVisible attribute explicitly set to false
|
||||||
|
and the type has ComVisible attribute explicitly set to true.
|
||||||
|
</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Interoperability.Com.AvoidNonPublicFieldsInComVisibleValueTypesRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for ComVisible value types which contain fields that are non-public.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[assembly: ComVisible (false)]
|
||||||
|
namespace InteropLibrary {
|
||||||
|
[ComVisible (true)]
|
||||||
|
public struct BadStruct {
|
||||||
|
internal int SomeValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
[assembly: ComVisible (false)]
|
||||||
|
namespace InteropLibrary {
|
||||||
|
[ComVisible (true)]
|
||||||
|
public struct BadStruct {
|
||||||
|
public int SomeValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Interoperability.Com.AvoidOverloadsInComVisibleInterfacesRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for ComVisible interface which contains overloaded methods.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[ComVisible(true)]
|
||||||
|
public interface Bad {
|
||||||
|
void SomeMethod();
|
||||||
|
void SomeMethod(int SomeValue);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
[ComVisible(true)]
|
||||||
|
public interface Good {
|
||||||
|
void SomeMethod();
|
||||||
|
void SomeMethodWithValue(int SomeValue);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Interoperability.Com.AvoidStaticMembersInComVisibleTypesRule">
|
||||||
|
<summary>
|
||||||
|
COM visible types should not contain static methods because they are
|
||||||
|
not supported by COM
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[assembly: ComVisible (false)]
|
||||||
|
namespace InteropLibrary {
|
||||||
|
[ComVisible (true)]
|
||||||
|
public class Bad {
|
||||||
|
public static void BadMethod ()
|
||||||
|
{
|
||||||
|
// do something
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
[assembly: ComVisible (false)]
|
||||||
|
namespace InteropLibrary {
|
||||||
|
[ComVisible (true)]
|
||||||
|
public class Good {
|
||||||
|
[ComVisiblte (false)]
|
||||||
|
public static void GoodMethod ()
|
||||||
|
{
|
||||||
|
// do something
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>
|
||||||
|
This rule ignores methods marked with ComRegisterFunctionAttribute or ComUnregisterFunctionAttribute attributes.
|
||||||
|
Rule applies only when the containing assembly has ComVisible attribute explicitly set to false
|
||||||
|
and the type has ComVisible attribute explicitly set to true.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Interoperability.Com.ComVisibleShouldInheritFromComVisibleRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks that the base type of COM visible types is also
|
||||||
|
visible from COM. This is needed reduce the chance of breaking
|
||||||
|
COM clients as COM invisible types do not have to follow COM versioning rules.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[assemply: ComVisible(false)]
|
||||||
|
namespace InteropLibrary {
|
||||||
|
[ComVisible (false)]
|
||||||
|
public class Base {
|
||||||
|
}
|
||||||
|
[ComVisible (true)]
|
||||||
|
public class Derived : Base {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
[assemply: ComVisible(false)]
|
||||||
|
namespace InteropLibrary {
|
||||||
|
[ComVisible (true)]
|
||||||
|
public class Base {
|
||||||
|
}
|
||||||
|
[ComVisible (true)]
|
||||||
|
public class Derived : Base {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (both types are invisible because of the assembly attribute):
|
||||||
|
<code>
|
||||||
|
[assemply: ComVisible(false)]
|
||||||
|
namespace InteropLibrary {
|
||||||
|
public class Base {
|
||||||
|
}
|
||||||
|
public class Derived : Base {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Interoperability.Com.ComVisibleTypesShouldBeCreatableRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for ComVisible reference types which have a public parameterized constructor,
|
||||||
|
but lack a default public constructor.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[ComVisible (true)]
|
||||||
|
public class BadClass {
|
||||||
|
public BadClass (int param) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
[ComVisible (true)]
|
||||||
|
public class GoodClass {
|
||||||
|
public GoodClass () {
|
||||||
|
}
|
||||||
|
public GoodClass (int param) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Interoperability.Com.DoNotUseAutoDualClassInterfaceTypeRule">
|
||||||
|
<summary>
|
||||||
|
Classes should not use ClassInterfaceAttribute with the value of
|
||||||
|
ClassInterfaceType.AutoDual because this may break COM clients
|
||||||
|
if the class layout changes.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[ComVisible (true)]
|
||||||
|
[ClassInterface (ClassInterfaceType.AutoDual)]
|
||||||
|
class Bad {
|
||||||
|
// do something
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (ClassInterfaceType.None):
|
||||||
|
<code>
|
||||||
|
[ComVisible (true)]
|
||||||
|
[ClassInterface (ClassInterfaceType.None)]
|
||||||
|
class Good : ICloneable {
|
||||||
|
public object Clone ()
|
||||||
|
{
|
||||||
|
return new object ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (no ClassInterface attribute, equal to ClassInterfaceType.AutoDispatch):
|
||||||
|
<code>
|
||||||
|
[ComVisible (true)]
|
||||||
|
class Good {
|
||||||
|
// do something
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Interoperability.Com.MarkComSourceInterfacesAsIDispatchRule">
|
||||||
|
<summary>
|
||||||
|
When a type is marked with the ComSourceInterfacesAttribute, every specified interface must
|
||||||
|
be marked with a InterfaceTypeAttribute set to ComInterfaceType.InterfaceIsIDispatch.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
interface IBadInterface { }
|
||||||
|
[ComSourceInterfaces("Project.IBadInterface")]
|
||||||
|
class TestClass { }
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
|
||||||
|
interface IGoodInterface { }
|
||||||
|
[ComSourceInterfaces("Project.IGoodInterface")]
|
||||||
|
class TestClass { }
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Interoperability.Com.ReviewComRegistrationMethodsRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks the correctness of COM register and unregister methods,
|
||||||
|
i.e. they should not be externally visible and they should be matched
|
||||||
|
(both or none of them should exist ).
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example (public methods):
|
||||||
|
<code>
|
||||||
|
[ComVisible (true)
|
||||||
|
class Bad {
|
||||||
|
[ComRegisterFunction]
|
||||||
|
public void Register ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
[ComUnregisterFunction]
|
||||||
|
public void Unregister ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Bad example (only one of the methods exist)
|
||||||
|
<code>
|
||||||
|
[ComVisible (true)]
|
||||||
|
class Bad {
|
||||||
|
[ComRegisterFunction]
|
||||||
|
public void Register ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
[ComVisible (true)]
|
||||||
|
class Good {
|
||||||
|
[ComRegisterFunction]
|
||||||
|
private void Register ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
[ComUnregisterFunction]
|
||||||
|
private void Unregister ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Interoperability.Com.ComRocks">
|
||||||
|
<summary>
|
||||||
|
ComRocks contains extensions methods for COM-related methods.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:Gendarme.Rules.Interoperability.Com.ComRocks.IsComVisible(Mono.Cecil.ICustomAttributeProvider)">
|
||||||
|
<summary>
|
||||||
|
Check if the type is explicitly declared to be ComVisible.
|
||||||
|
</summary>
|
||||||
|
<param name="self">The ICustomAttributeProvider (e.g. AssemblyDefinition, TypeReference, MethodReference,
|
||||||
|
FieldReference...) on which the extension method can be called.</param>
|
||||||
|
<returns>
|
||||||
|
<code>null</code> no ComVisible attribute is present, <code>true</code> if ComVisible is set to true, <code>false</code> otherwise.</returns>
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
|
</doc>
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -0,0 +1,245 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<doc>
|
||||||
|
<assembly>
|
||||||
|
<name>Gendarme.Rules.Interoperability</name>
|
||||||
|
</assembly>
|
||||||
|
<members>
|
||||||
|
<member name="T:Gendarme.Rules.Interoperability.CentralizePInvokesIntoNativeMethodsTypeRule">
|
||||||
|
<summary>
|
||||||
|
This rule will warn you if p/invoke declarations are found outside some
|
||||||
|
specially named types. The convention makes it easier to know which type
|
||||||
|
of security checks are done (at runtime) and how critical is a security
|
||||||
|
audit for them. In all cases the type should not be visible (i.e. <c>internal</c>
|
||||||
|
in C#) outside the assembly.
|
||||||
|
Note that the type naming itself has no influence on security (either with
|
||||||
|
Code Access Security or with CoreCLR for Silverlight). The naming convention
|
||||||
|
includes the presence or absence of the <c>[SuppressUnmanagedCodeSecurity]</c>
|
||||||
|
security attribute based on the type name.
|
||||||
|
<list><item><description><c>NativeMethods</c> should not be decorated with a
|
||||||
|
<c>[SuppressUnmanagedCodeSecurity]</c>. This will let CAS do a stackwalk to
|
||||||
|
ensure the code can be...</description></item><item><description><c>SafeNativeMethods</c> should be decorated with a
|
||||||
|
<c>[SuppressUnmanagedCodeSecurity] attribute</c>. The attribute means that no
|
||||||
|
stackwalk will occurs.</description></item><item><description><c>UnsafeNativeMethods</c> should be decorated with a
|
||||||
|
<c>[SuppressUnmanagedCodeSecurity] attribute</c>. The attribute means that no
|
||||||
|
stackwalk will occurs. However since the p/invoke methods are named unsafe then
|
||||||
|
the rule will warn an audit-level defect to review the code.</description></item></list></summary>
|
||||||
|
<remarks>This rule is available since Gendarme 2.8</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Interoperability.DelegatesPassedToNativeCodeMustIncludeExceptionHandlingRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for delegates which are created for methods which don't
|
||||||
|
have exception handling and then passed to native code.
|
||||||
|
Every delegate which is passed to native code must include an exception
|
||||||
|
block which spans the entire method and has a catch all block.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
delegate void Callback ();
|
||||||
|
[DllImport ("mylibrary.dll")]
|
||||||
|
static extern void RegisterCallback (Callback callback);
|
||||||
|
public void RegisterManagedCallback ()
|
||||||
|
{
|
||||||
|
RegisterCallback (ManagedCallback);
|
||||||
|
}
|
||||||
|
public void ManagedCallback ()
|
||||||
|
{
|
||||||
|
// This will cause the process to crash if native code calls this method.
|
||||||
|
throw new NotImplementedException ();
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
delegate void Callback ();
|
||||||
|
[DllImport ("mylibrary.dll")]
|
||||||
|
static extern void RegisterCallback (Callback callback);
|
||||||
|
public void RegisterManagedCallback ()
|
||||||
|
{
|
||||||
|
RegisterCallback (ManagedCallback);
|
||||||
|
}
|
||||||
|
public void ManagedCallback ()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
throw new NotImplementedException ();
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
// This way the exception won't "leak" to native code
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
throw new NotImplementedException ();
|
||||||
|
}
|
||||||
|
catch (System.Exception ex) {
|
||||||
|
// This is also safe - the runtime will process this catch clause,
|
||||||
|
// even if it is technically possible (by writing assemblies in managed
|
||||||
|
// C++ or IL) to throw an exception that doesn't inherit from
|
||||||
|
// System.Exception.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.6</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Interoperability.DoNotAssumeIntPtrSizeRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for code which casts an <code>IntPtr</code> or <code>UIntPtr</code> into a
|
||||||
|
32-bit (or smaller) value. It will also check if memory read with the <c>Marshal.ReadInt32</c>
|
||||||
|
and <c>Marshal.ReadInt64</c> methods is being cast into an <code>IntPtr</code> or
|
||||||
|
<code>UIntPtr</code>. <code>IntPtr</code> is generally used to reference a memory
|
||||||
|
location and downcasting them to 32-bits will make the code fail on 64-bit CPUs.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example (cast):
|
||||||
|
<code>
|
||||||
|
int ptr = dest.ToInt32 ();
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
Marshal.StructureToPtr (this, (IntPtr)ptr, false);
|
||||||
|
ptr += 4;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Bad example (Marshal.Read*):
|
||||||
|
<code>
|
||||||
|
// that won't work on 64 bits platforms
|
||||||
|
IntPtr p = (IntPtr) Marshal.ReadInt32 (p);
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (cast):
|
||||||
|
<code>
|
||||||
|
long ptr = dest.ToInt64 ();
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
Marshal.StructureToPtr (this, (IntPtr) ptr, false);
|
||||||
|
ptr += IntPtr.Size;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (Marshal.Read*):
|
||||||
|
<code>
|
||||||
|
IntPtr p = (IntPtr) Marshal.ReadIntPtr (p);
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.0 but was named DoNotCastIntPtrToInt32Rule before 2.2</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Interoperability.GetLastErrorMustBeCalledRightAfterPInvokeRule">
|
||||||
|
<summary>
|
||||||
|
This rule will fire if <code>Marshal.GetLastWin32Error()</code> is called, but is
|
||||||
|
not called immediately after a P/Invoke. This is a problem because other methods,
|
||||||
|
even managed methods, may overwrite the error code.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public void DestroyError ()
|
||||||
|
{
|
||||||
|
MessageBeep (2);
|
||||||
|
Console.WriteLine ("Beep");
|
||||||
|
int error = Marshal.GetLastWin32Error ();
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public void GetError ()
|
||||||
|
{
|
||||||
|
MessageBeep (2);
|
||||||
|
int error = Marshal.GetLastWin32Error ();
|
||||||
|
Console.WriteLine ("Beep");
|
||||||
|
}
|
||||||
|
public void DontUseGetLastError ()
|
||||||
|
{
|
||||||
|
MessageBeep (2);
|
||||||
|
Console.WriteLine ("Beep");
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Interoperability.MarshalBooleansInPInvokeDeclarationsRule">
|
||||||
|
<summary>
|
||||||
|
This rule warns the developer if a <code>[MarshalAs]</code> attribute has not been
|
||||||
|
specified for boolean parameters of a P/Invoke method. The size of boolean types varies
|
||||||
|
across language (e.g. the C++ <c>bool</c> type is four bytes on some platforms and
|
||||||
|
one byte on others). By default the CLR will marshal <b>System.Boolean</b> as a 32 bit value
|
||||||
|
(<c>UnmanagedType.Bool</c>) like the Win32 API <b>BOOL</b> uses. But, for clarity,
|
||||||
|
you should always specify the correct value.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
// bad assuming the last parameter is a single byte being mapped to a bool
|
||||||
|
[DllImport ("liberty")]
|
||||||
|
private static extern bool Bad (bool b1, ref bool b2);
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
[DllImport ("liberty")]
|
||||||
|
[return: MarshalAs (UnmanagedType.Bool)]
|
||||||
|
private static extern bool Good ([MarshalAs (UnmanagedType.Bool)] bool b1, [MarshalAs (UnmanagedType.U1)] ref bool b2);
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Interoperability.MarshalStringsInPInvokeDeclarationsRule">
|
||||||
|
<summary>
|
||||||
|
This rule will fire if a P/Invoke method has System.String or System.Text.StringBuilder
|
||||||
|
arguments, and the DllImportAttribute does not specify the <code>CharSet</code>,
|
||||||
|
and the string arguments are not decorated with <code>[MarshalAs]</code>.
|
||||||
|
This is important because the defaults are different on the various platforms.
|
||||||
|
On Mono the default is to always use utf-8. On .NET the default is to use the ANSI
|
||||||
|
CharSet which is the native encoding and will typically be some variant of ASCII or
|
||||||
|
something like Shift-JIS. On Compact .NET the default is utf-16.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[DllImport ("coredll")]
|
||||||
|
static extern int SHCreateShortcut (StringBuilder szShortcut, StringBuilder szTarget);
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good examples:
|
||||||
|
<code>
|
||||||
|
[DllImport ("coredll", CharSet = CharSet.Auto)]
|
||||||
|
static extern int SHCreateShortcut (StringBuilder szShortcut, StringBuilder szTarget);
|
||||||
|
[DllImport ("coredll")]
|
||||||
|
static extern int SHCreateShortcut ([MarshalAs (UnmanagedType.LPTStr)] StringBuilder szShortcut,
|
||||||
|
[MarshalAs (UnmanagedType.LPTStr)] StringBuilder szTarget);
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Interoperability.PInvokeShouldNotBeVisibleRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for PInvoke declaration methods that are visible outside their assembly.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[DllImport ("user32.dll")]
|
||||||
|
public static extern bool MessageBeep (UInt32 beepType);
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
[DllImport ("user32.dll")]
|
||||||
|
internal static extern bool MessageBeep (UInt32 beepType);
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Interoperability.UseManagedAlternativesToPInvokeRule">
|
||||||
|
<summary>
|
||||||
|
This rule will fire if an external (P/Invoke) method is called but a managed
|
||||||
|
alternative is provided by the .NET framework.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[DllImport ("kernel32.dll")]
|
||||||
|
static extern void Sleep (uint dwMilliseconds);
|
||||||
|
public void WaitTwoSeconds ()
|
||||||
|
{
|
||||||
|
Sleep (2000);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public void WaitTwoSeconds ()
|
||||||
|
{
|
||||||
|
System.Threading.Thread.Sleep (2000);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
|
</doc>
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -0,0 +1,312 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<doc>
|
||||||
|
<assembly>
|
||||||
|
<name>Gendarme.Rules.Maintainability</name>
|
||||||
|
</assembly>
|
||||||
|
<members>
|
||||||
|
<member name="T:Gendarme.Rules.Maintainability.AvoidAlwaysNullFieldRule">
|
||||||
|
<summary>
|
||||||
|
A type has a private field whose value is always null.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
internal sealed class Bad {
|
||||||
|
private List<int> values;
|
||||||
|
public List<int> Values {
|
||||||
|
get {
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
internal sealed class Good {
|
||||||
|
private List<int> values = new List<int>();
|
||||||
|
public List<int> Values {
|
||||||
|
get {
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.4</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Maintainability.AvoidComplexMethodsRule">
|
||||||
|
<summary>
|
||||||
|
This rule computes the cyclomatic complexity (CC) for every method and reports any method
|
||||||
|
with a CC over 25 (this limit is configurable). Large CC value often indicate complex
|
||||||
|
code that is hard to understand and maintain. It's likely that breaking the
|
||||||
|
method into several methods will help readability. This rule won't report any defects
|
||||||
|
on code generated by the compiler or by tools.
|
||||||
|
</summary>
|
||||||
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="P:Gendarme.Rules.Maintainability.AvoidComplexMethodsRule.SuccessThreshold">
|
||||||
|
<summary>The cyclomatic complexity at which defects begin to be reported.</summary>
|
||||||
|
<remarks>This defaults to 25 and larger values will mean fewer reported defects.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="P:Gendarme.Rules.Maintainability.AvoidComplexMethodsRule.LowThreshold">
|
||||||
|
<summary>Methods with cyclomatic complexity less than this will be reported as low severity.</summary>
|
||||||
|
<remarks>If left as zero then the rule will initialize it to 2*SuccessThreshold.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="P:Gendarme.Rules.Maintainability.AvoidComplexMethodsRule.MediumThreshold">
|
||||||
|
<summary>Methods with cyclomatic complexity less than this (but higher than LowThreshold) will be reported as medium severity.</summary>
|
||||||
|
<remarks>If left as zero then the rule will initialize it to 3*SuccessThreshold.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="P:Gendarme.Rules.Maintainability.AvoidComplexMethodsRule.HighThreshold">
|
||||||
|
<summary>Methods with cyclomatic complexity less than this (but higher than MediumThreshold) will be reported as high severity.</summary>
|
||||||
|
<remarks>Methods with cyclomatic complexity greater than this will be reported as critical severity.
|
||||||
|
If left as zero then the rule will initialize it to 4*SuccessThreshold.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Maintainability.AvoidDeepInheritanceTreeRule">
|
||||||
|
<summary>
|
||||||
|
This rule will fire if a type has (by default) more than four base classes defined
|
||||||
|
within the assembly set being analyzed. Optionally it will also count base
|
||||||
|
classes defined outside the assembly set being analyzed.
|
||||||
|
</summary>
|
||||||
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="P:Gendarme.Rules.Maintainability.AvoidDeepInheritanceTreeRule.MaximumDepth">
|
||||||
|
<summary>Classes with more base classes than this will result in a defect.</summary>
|
||||||
|
<remarks>Defaults to 4.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="P:Gendarme.Rules.Maintainability.AvoidDeepInheritanceTreeRule.CountExternalDepth">
|
||||||
|
<summary>If true the rule will count base classes defined outside the assemblies being analyzed.</summary>
|
||||||
|
<remarks>Defaults to false.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Maintainability.AvoidLackOfCohesionOfMethodsRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks every type for lack of cohesion between the fields and the methods. Low cohesion is often
|
||||||
|
a sign that a type is doing too many, different and unrelated things. The cohesion score is given for each defect
|
||||||
|
(higher is better).
|
||||||
|
Automatic properties (e.g. available in C# 3) are considered as fields since their 'backing field' cannot be
|
||||||
|
directly used and the getter/setter is only used to update a single field.
|
||||||
|
</summary>
|
||||||
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="P:Gendarme.Rules.Maintainability.AvoidLackOfCohesionOfMethodsRule.SuccessLowerLimit">
|
||||||
|
<summary>Cohesion values lower than this will result in a defect.</summary>
|
||||||
|
<remarks>Defaults to 0.5.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="P:Gendarme.Rules.Maintainability.AvoidLackOfCohesionOfMethodsRule.LowSeverityLowerLimit">
|
||||||
|
<summary>Defects with cohesion values greater than this will be reported at low severity.</summary>
|
||||||
|
<remarks>Defaults to 0.4.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="P:Gendarme.Rules.Maintainability.AvoidLackOfCohesionOfMethodsRule.MediumSeverityLowerLimit">
|
||||||
|
<summary>Defects with cohesion values greater than (but less than LowSeverityLowerLimit) this will be reported at medium severity.</summary>
|
||||||
|
<remarks>Defaults to 0.2.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="P:Gendarme.Rules.Maintainability.AvoidLackOfCohesionOfMethodsRule.MinimumMethodCount">
|
||||||
|
<summary>The minimum number of methods a class must have to be checked.</summary>
|
||||||
|
<remarks>Defaults to 2.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="P:Gendarme.Rules.Maintainability.AvoidLackOfCohesionOfMethodsRule.MinimumFieldCount">
|
||||||
|
<summary>The minimum number of fields a class must have to be checked.</summary>
|
||||||
|
<remarks>Defaults to 1.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Maintainability.AvoidUnnecessarySpecializationRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks methods for over specialized parameters - i.e. parameter types
|
||||||
|
that are unnecessarily specialized with respect to what the method needs to
|
||||||
|
perform its job. This often impairs the reusability of the method. If a problem
|
||||||
|
is found the rule will suggest the most general type, or interface, required for the
|
||||||
|
method to work.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public class DefaultEqualityComparer : IEqualityComparer {
|
||||||
|
public int GetHashCode (object obj)
|
||||||
|
{
|
||||||
|
return o.GetHashCode ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public int Bad (DefaultEqualityComparer ec, object o)
|
||||||
|
{
|
||||||
|
return ec.GetHashCode (o);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public class DefaultEqualityComparer : IEqualityComparer {
|
||||||
|
public int GetHashCode (object obj)
|
||||||
|
{
|
||||||
|
return o.GetHashCode ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public int Good (IEqualityComparer ec, object o)
|
||||||
|
{
|
||||||
|
return ec.GetHashCode (o);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Maintainability.ConsiderUsingStopwatchRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks methods for cases where a <c>System.Diagnostics.Stopwatch</c> could be
|
||||||
|
used instead of using <c>System.DateTime</c> to compute the time required for an action.
|
||||||
|
Stopwatch is preferred because it better expresses the intent of the code and because (on
|
||||||
|
some platforms at least) StopWatch is accurate to roughly the microsecond whereas
|
||||||
|
DateTime.Now is only accurate to 16 milliseconds or so. This rule only applies to assemblies
|
||||||
|
compiled with the .NET framework version 2.0 (or later).
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public TimeSpan DoLongOperation ()
|
||||||
|
{
|
||||||
|
DateTime start = DateTime.Now;
|
||||||
|
DownloadNewOpenSuseDvdIso ();
|
||||||
|
return DateTime.Now - start;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public TimeSpan DoLongOperation ()
|
||||||
|
{
|
||||||
|
Stopwatch watch = Stopwatch.StartNew ();
|
||||||
|
DownloadNewOpenSuseDvdIso ();
|
||||||
|
return watch.Elapsed;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Maintainability.PreferStringIsNullOrEmptyRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks methods for cases where <c>String.IsNullOrEmpty</c> could be
|
||||||
|
used instead of doing separate null and length checks. This does not affect
|
||||||
|
execution nor performance (much) but it does improve source code readability.
|
||||||
|
This rule only applies to assemblies compiled with .NET 2.0 (or later).
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public bool SendMessage (string message)
|
||||||
|
{
|
||||||
|
if ((message == null) || (message.Length == 0)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return SendMessage (Encode (message));
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public bool SendMessage (string message)
|
||||||
|
{
|
||||||
|
if (String.IsNullOrEmpty (message)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return SendMessage (Encode (message));
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Maintainability.RemoveDependenceOnObsoleteCodeRule">
|
||||||
|
<summary>
|
||||||
|
This rule will warn you if your code depends on (e.g. inherit, implement, call...)
|
||||||
|
code that is decorated with the <c>[Obsolete]</c> attribute.
|
||||||
|
Note that the rule does not report <c>[Obsolete]</c> types, methods...
|
||||||
|
but only their use by your code.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[Obsolete ("Limited to In32.MaxValue, use new Int64 ReportAll method")]
|
||||||
|
abstract int Report (IList list);
|
||||||
|
abstract long ReportAll (IList list);
|
||||||
|
public int GetCount ()
|
||||||
|
{
|
||||||
|
// this method is not ok since it use an obsolete method
|
||||||
|
return Report (list);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (dependency removed):
|
||||||
|
<code>
|
||||||
|
[Obsolete ("Limited to In32.MaxValue, use new Int64 ReportAll method")]
|
||||||
|
abstract int Report (IList list);
|
||||||
|
abstract long ReportAll (IList list);
|
||||||
|
// this method is correct but this changed the public API
|
||||||
|
public long GetCount ()
|
||||||
|
{
|
||||||
|
return ReportAll (list);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (decorated as [Obsolete]):
|
||||||
|
<code>
|
||||||
|
[Obsolete ("Limited to In32.MaxValue, use new Int64 ReportAll method")]
|
||||||
|
abstract int Report (IList list);
|
||||||
|
abstract long ReportAll (IList list);
|
||||||
|
[Obsolete ("Limited to In32.MaxValue, use new Int64 GetLongCount method")]
|
||||||
|
public int GetCount ()
|
||||||
|
{
|
||||||
|
// this method is now correct since it is decorated with [Obsolete]
|
||||||
|
return Report (list);
|
||||||
|
}
|
||||||
|
public long GetLongCount ()
|
||||||
|
{
|
||||||
|
return ReportAll (list);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.8</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Maintainability.ReviewMisleadingFieldNamesRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for fields which have misleading names, e.g. instance fields beginning with "s_"
|
||||||
|
or static fields beginning with "m_", since they can be confusing when reading source code.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public class Bad {
|
||||||
|
int s_value;
|
||||||
|
static int m_other_value;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public class Good {
|
||||||
|
int value;
|
||||||
|
static int other_value;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Maintainability.VariableNamesShouldNotMatchFieldNamesRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for local variables or parameters whose names match (case sensitive) an instance field name.
|
||||||
|
Note that variable names can only be verified when debugging symbols (pdb or mdb) are available.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public class Bad {
|
||||||
|
public int value;
|
||||||
|
public void DoSomething (int value)
|
||||||
|
{
|
||||||
|
// without 'this.' the field will never be set
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public class Good {
|
||||||
|
public int value;
|
||||||
|
public void DoSomething (int integralValue)
|
||||||
|
{
|
||||||
|
value = integralValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
|
</doc>
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -0,0 +1,102 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<doc>
|
||||||
|
<assembly>
|
||||||
|
<name>Gendarme.Rules.NUnit</name>
|
||||||
|
</assembly>
|
||||||
|
<members>
|
||||||
|
<member name="T:Gendarme.Rules.NUnit.NUnitRocks">
|
||||||
|
<summary>
|
||||||
|
NUnitRocks contains extensions methods for NUnit-related methods and types.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:Gendarme.Rules.NUnit.NUnitRocks.IsTest(Mono.Cecil.ICustomAttributeProvider)">
|
||||||
|
<summary>
|
||||||
|
Checks if the method is a valid unit test (has corresponding attribute).
|
||||||
|
</summary>
|
||||||
|
<param name="self">The ICustomAttributeProvider on which the extension method can be called.</param>
|
||||||
|
<returns>True if method is a unit test, false otherwise.</returns>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.NUnit.ProvideMessageOnAssertCallsRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks that all Assert.* methods are calling with 'message'
|
||||||
|
parameter, which helps to easily identify failing test.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[Test]
|
||||||
|
public void TestThings ()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(10, 20);
|
||||||
|
Assert.AreEqual(30, 40);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
[Test]
|
||||||
|
public void TestThings ()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(10, 20, "10 equal to 20 test");
|
||||||
|
Assert.AreEqual(30, 40, "30 equal to 40 test");
|
||||||
|
</code></example>
|
||||||
|
<remarks>
|
||||||
|
This rule will not report any problems if only one Assert.* call was made
|
||||||
|
inside a method, because it's easy to identify failing test in this case.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.NUnit.TestMethodsMustBePublicRule">
|
||||||
|
<summary>
|
||||||
|
Test method (a method, marked with either TestAttribute, TestCaseAttribute
|
||||||
|
or TestCaseSourceAttribute) is not public. Most NUnit test runners won't
|
||||||
|
execute non-public unit tests.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[Test]
|
||||||
|
private void TestMethod ()
|
||||||
|
{
|
||||||
|
Assert.AreEqual (10, 20);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public void TestMethod ()
|
||||||
|
{
|
||||||
|
Assert.AreEqual (10, 20);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.NUnit.UnitTestsMissingTestFixtureRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks that all types which have methods with TestAttribute, TestCaseAttribute
|
||||||
|
or TestCaseSourceAttribute are marked with the TestFixtureAttribute. NUnit < 2.5 will not run
|
||||||
|
tests located in types without TestFixtureAttribute.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
class Test {
|
||||||
|
[Test]
|
||||||
|
public void TestMethod ()
|
||||||
|
{
|
||||||
|
Assert.AreEqual (0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
[TestFixture]
|
||||||
|
class Test {
|
||||||
|
[Test]
|
||||||
|
public void TestMethod ()
|
||||||
|
{
|
||||||
|
Assert.AreEqual (0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
|
</doc>
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -0,0 +1,490 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<doc>
|
||||||
|
<assembly>
|
||||||
|
<name>Gendarme.Rules.Naming</name>
|
||||||
|
</assembly>
|
||||||
|
<members>
|
||||||
|
<member name="T:Gendarme.Rules.Naming.AvoidDeepNamespaceHierarchyRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for deeply nested namespaces within an assembly. It will
|
||||||
|
warn if the depth is greater than four (default value) unless the fifth (or the
|
||||||
|
next) part is one of the specialized name that the framework recommends or a
|
||||||
|
name like an internal namespace (something not meant to be seen outside the assembly).
|
||||||
|
<list><item><term>Design</term><description>Namespace that provides design-time
|
||||||
|
support for its base namespace.</description></item><item><term>Interop</term><description>Namespace that provides all interoperability
|
||||||
|
code (e.g. p./invokes) for its base namespace.</description></item><item><term>Permissions</term><description>Namespace that provides all custom
|
||||||
|
permissions for its base namespace.</description></item><item><term>Internal</term><description>Namespace that provides non visible (outside
|
||||||
|
the assembly) helper code for its base namespace. <c>Impl</c> while allowed by the
|
||||||
|
rule is not encouraged.
|
||||||
|
</description></item></list></summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
namespace One.Two.Three.Four.Five {
|
||||||
|
internal class Helper {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
namespace One.Two.Three.Four {
|
||||||
|
internal class FiveHelper {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (exception for some namespace specialization):
|
||||||
|
<code>
|
||||||
|
namespace One.Two.Three.Four.Internal {
|
||||||
|
internal class Helper {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="P:Gendarme.Rules.Naming.AvoidDeepNamespaceHierarchyRule.MaxDepth">
|
||||||
|
<summary>The depth at which namespaces may be nested without triggering a defect.</summary>
|
||||||
|
<remarks>Defaults to 4.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Naming.AvoidRedundancyInMethodNameRule">
|
||||||
|
<summary>
|
||||||
|
This rule will fire if a method name embeds the type name of its first parameter.
|
||||||
|
Usually, removing that type name makes the API less
|
||||||
|
verbose, easier to learn, and more future-proof.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
class PostOffice {
|
||||||
|
public void SendLetter (Letter letter) {
|
||||||
|
}
|
||||||
|
public void SendPackage (Package package) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
class PostOffice {
|
||||||
|
public void Send (Letter letter) {
|
||||||
|
}
|
||||||
|
public void Send (Package package) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
class PostOffice {
|
||||||
|
public static bool IsPackageValid (Package package) {
|
||||||
|
return package.HasAddress && package.HasStamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
class Package {
|
||||||
|
public bool IsValid {
|
||||||
|
get {
|
||||||
|
return HasAddress && HasStamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Naming.AvoidRedundancyInTypeNameRule">
|
||||||
|
<summary>
|
||||||
|
This rule will fire if a type is prefixed with the last component of its namespace.
|
||||||
|
Using prefixes like this makes type names more verbose than they need to be
|
||||||
|
and makes them harder to use with tools like auto-complete. Note that an
|
||||||
|
exception is made if removal of the prefix would cause an ambiguity with another
|
||||||
|
type. If this is the case the rule will not report a defect.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
namespace Foo.Lang.Compiler {
|
||||||
|
public class CompilerContext {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code><code>
|
||||||
|
using Foo.Lang;
|
||||||
|
...
|
||||||
|
Compiler.CompilerContext context = new Compiler.CompilerContext ();
|
||||||
|
</code><code>
|
||||||
|
using Foo.Lang.Compiler;
|
||||||
|
...
|
||||||
|
CompilerContext context = new CompilerContext ();
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
namespace Foo.Lang.Compiler {
|
||||||
|
public class Context {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code><code>
|
||||||
|
using Foo.Lang;
|
||||||
|
...
|
||||||
|
Compiler.Context context = new Compiler.Context ();
|
||||||
|
</code><code>
|
||||||
|
using Foo.Lang.Compiler;
|
||||||
|
...
|
||||||
|
Context context = new Context ();
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Another good example (more meaningful term in the context of the namespace):
|
||||||
|
<code>
|
||||||
|
namespace Foo.Lang.Compiler {
|
||||||
|
public class CompilationContext {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Naming.AvoidTypeInterfaceInconsistencyRule">
|
||||||
|
<summary>
|
||||||
|
This rule will fire if an assembly has a namespace which contains an interface IFoo
|
||||||
|
and a type Foo, but the type does not implement the interface. If an interface and
|
||||||
|
a type name differ only by the <c>I</c> prefix (of the interface) then we can
|
||||||
|
logically expect the type to implement this interface.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public interface IMember {
|
||||||
|
string Name {
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class Member {
|
||||||
|
public string Name {
|
||||||
|
get {
|
||||||
|
return String.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public interface IMember {
|
||||||
|
string Name {
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class Member : IMember {
|
||||||
|
public string Name {
|
||||||
|
get {
|
||||||
|
return String.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.4</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Naming.AvoidNonAlphanumericIdentifierRule">
|
||||||
|
<summary>
|
||||||
|
This rule ensures that identifiers like assembly names, namespaces, types and
|
||||||
|
members names don't have any non-alphanumerical characters inside them. The rule
|
||||||
|
will ignore interfaces used for COM interoperability - i.e. decorated with both
|
||||||
|
<c>[InterfaceType]</c> and <c>[Guid]</c> attributes.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
namespace New_Namespace {
|
||||||
|
public class My_Custom_Class {
|
||||||
|
public int My_Field;
|
||||||
|
public void My_Method (string my_string)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
namespace NewNamespace {
|
||||||
|
public class MyCustomClass {
|
||||||
|
public int MyField;
|
||||||
|
public void MyMethod (string myString)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>Prior to Gendarme 2.2 this rule was named DetectNonAlphanumericInTypeNamesRule</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Naming.DoNotPrefixEventsWithAfterOrBeforeRule">
|
||||||
|
<summary>
|
||||||
|
This rule ensures that event names are not prefixed with <c>After</c> or <c>Before</c>.
|
||||||
|
The .NET naming conventions recommend using a verb in the present and in
|
||||||
|
the past tense.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public class Bad {
|
||||||
|
public event ResolveEventHandler BeforeResolve;
|
||||||
|
public event ResolveEventHandler AfterResolve;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public class Good {
|
||||||
|
public event ResolveEventHandler Resolving; // present
|
||||||
|
public event ResolveEventHandler Resolved; // past
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Naming.DoNotPrefixValuesWithEnumNameRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for <c>enum</c> values that are prefixed with the enumeration type
|
||||||
|
name. This is typical in C/C++ application but unneeded in .NET since the <c>enum</c>
|
||||||
|
type name must be specified anyway when used.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public enum Answer {
|
||||||
|
AnswerYes,
|
||||||
|
AnswerNo,
|
||||||
|
AnswerMaybe,
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public enum Answer {
|
||||||
|
Yes,
|
||||||
|
No,
|
||||||
|
Maybe
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Naming.DoNotUseReservedInEnumValueNamesRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for enumerations that contain values named <c>reserved</c>. This
|
||||||
|
practice, often seen in C/C++ sources, is not needed in .NET since adding new
|
||||||
|
values will not normally break binary compatibility. However renaming a <c>reserved</c>
|
||||||
|
enum value can since there is no way to prevent people from using the old value.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public enum Answer {
|
||||||
|
Yes,
|
||||||
|
No,
|
||||||
|
Reserved
|
||||||
|
// ^ renaming this to 'Maybe' would be a breaking change
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public enum Answer {
|
||||||
|
Yes,
|
||||||
|
No
|
||||||
|
// we can add Maybe here without causing a breaking change
|
||||||
|
// (but note that we may break code if we change the values of
|
||||||
|
// existing enumerations)
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Naming.ParameterNamesShouldMatchOverriddenMethodRule">
|
||||||
|
<summary>
|
||||||
|
This rule warns if an overriden method's parameter names does not match those of the
|
||||||
|
base class or those of the implemented interface. This can be confusing because it may
|
||||||
|
not always be clear that it is an override or implementation of an interface method. It
|
||||||
|
also makes it more difficult to use the method with languages that support named
|
||||||
|
parameters (like C# 4.0).
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public class Base {
|
||||||
|
public abstract void Write (string text);
|
||||||
|
}
|
||||||
|
public class SubType : Base {
|
||||||
|
public override void Write (string output)
|
||||||
|
{
|
||||||
|
//...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public class Base {
|
||||||
|
public abstract void Write (string text);
|
||||||
|
}
|
||||||
|
class SubType : Base {
|
||||||
|
public override void Write (string text)
|
||||||
|
{
|
||||||
|
//...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Naming.UseCorrectCasingRule">
|
||||||
|
<summary>
|
||||||
|
This rule ensures that identifiers are correctly cased. In particular:
|
||||||
|
<list><item><description>namespace names are PascalCased</description></item><item><description>type names are PascalCased</description></item><item><description>method names are PascalCased</description></item><item><description>parameter names are camelCased</description></item></list></summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
namespace A {
|
||||||
|
abstract public class myClass {
|
||||||
|
abstract public int thisMethod (int ThatParameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
namespace Company.Product.Technology {
|
||||||
|
abstract public class MyClass {
|
||||||
|
abstract public int ThisMethod (int thatParameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Naming.UseCorrectPrefixRule">
|
||||||
|
<summary>
|
||||||
|
This rule ensures that types are prefixed correctly. Interfaces should always be prefixed
|
||||||
|
with a <c>I</c>, types should never be prefixed with a <c>C</c> (reminder for MFC folks)
|
||||||
|
and generic parameters should be a single, uppercased letter or be prefixed with <c>T</c>.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad examples:
|
||||||
|
<code>
|
||||||
|
public interface Phone {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
public class CPhone : Phone {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
public class Call<Mechanism> {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good examples:
|
||||||
|
<code>
|
||||||
|
public interface IPhone {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
public class Phone : IPhone {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
public class Call<TMechanism> {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Naming.UseCorrectSuffixRule">
|
||||||
|
<summary>
|
||||||
|
This rule ensure that types that inherit from certain types or implement certain interfaces
|
||||||
|
have a specific suffix. It also ensures that no other
|
||||||
|
types are using those suffixes without inheriting/implementing the types/interfaces. E.g.
|
||||||
|
<list><item><description><c>System.Attribute</c> should end with <c>Attribute</c></description></item><item><description><c>System.EventArgs</c> should end with <c>EventArgs</c></description></item><item><description><c>System.Exception</c> should end with <c>Exception</c></description></item><item><description><c>System.Collections.Queue</c> should end with <c>Collection</c> or <c>Queue</c></description></item><item><description><c>System.Collections.Stack</c> should end with <c>Collection</c> or <c>Stack</c></description></item><item><description><c>System.Data.DataSet</c> should end with <c>DataSet</c></description></item><item><description><c>System.Data.DataTable</c> should end with <c>DataTable</c> or <c>Collection</c></description></item><item><description><c>System.IO.Stream</c> should end with <c>Stream</c></description></item><item><description><c>System.Security.IPermission</c> should end with <c>Permission</c></description></item><item><description><c>System.Security.Policy.IMembershipCondition</c> should end with <c>Condition</c></description></item><item><description><c>System.Collections.IDictionary</c> or <c>System.Collections.Generic.IDictionary</c> should end with <c>Dictionary</c></description></item><item><description><c>System.Collections.ICollection</c>, <c>System.Collections.Generic.ICollection</c> or <c>System.Collections.IEnumerable</c> should end with <c>Collection</c></description></item></list></summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public sealed class SpecialCode : Attribute {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public sealed class SpecialCodeAttribute : Attribute {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Naming.UsePluralNameInEnumFlagsRule">
|
||||||
|
<summary>
|
||||||
|
This rule ensures that the name of enumerations decorated with FlagsAttribute are
|
||||||
|
in plural form.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[Flags]
|
||||||
|
public enum MyCustomValue {
|
||||||
|
Foo,
|
||||||
|
Bar,
|
||||||
|
AllValues = Foo | Bar
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
[Flags]
|
||||||
|
public enum MyCustomValues {
|
||||||
|
Foo,
|
||||||
|
Bar,
|
||||||
|
AllValues = Foo | Bar
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Naming.UsePreferredTermsRule">
|
||||||
|
<summary>
|
||||||
|
This rule ensures that identifiers such as assemblies, namespaces, types, and members,
|
||||||
|
use the terms suggested by the .NET framework guidelines so that they are consistent
|
||||||
|
with other class libraries.
|
||||||
|
<list><item><description><c>Arent</c> should be replaced with <c>AreNot</c>;</description></item><item><description><c>Cancelled</c> should be replaced with <c>Canceled</c>;</description></item><item><description><c>Cant</c> should be replaced with <c>Cannot</c>;</description></item><item><description><c>ComPlus</c> should be replaced with <c>EnterpriseServices</c>;</description></item><item><description><c>Couldnt</c> should be replaced with <c>CouldNot</c>;</description></item><item><description><c>Didnt</c> should be replaced with <c>DidNot</c>;</description></item><item><description><c>Doesnt</c> should be replaced with <c>DoesNot</c>;</description></item><item><description><c>Dont</c> should be replaced with <c>DoNot</c>;</description></item><item><description><c>Hadnt</c> should be replaced with <c>HadNot</c>;</description></item><item><description><c>Hasnt</c> should be replaced with <c>HasNot</c>;</description></item><item><description><c>Havent</c> should be replaced with <c>HaveNot</c>;</description></item><item><description><c>Indices</c> should be replaced with <c>Indexes</c>;</description></item><item><description><c>Isnt</c> should be replaced with <c>IsNot</c>;</description></item><item><description><c>LogIn</c> should be replaced with <c>LogOn</c>;</description></item><item><description><c>LogOut</c> should be replaced with <c>LogOff</c>;</description></item><item><description><c>Shouldnt</c> should be replaced with <c>ShouldNot</c>;</description></item><item><description><c>SignOn</c> should be replaced with <c>SignIn</c>;</description></item><item><description><c>SignOff</c> should be replaced with <c>SignOut</c>;</description></item><item><description><c>Wasnt</c> should be replaced with <c>WasNot</c>;</description></item><item><description><c>Werent</c> should be replaced with <c>WereNot</c>;</description></item><item><description><c>Wont</c> should be replaced with <c>WillNot</c>;</description></item><item><description><c>Wouldnt</c> should be replaced with <c>WouldNot</c>;</description></item><item><description><c>Writeable</c> should be replaced with <c>Writable</c>;</description></item></list></summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
abstract public class ComPlusSecurity {
|
||||||
|
abstract public void LogIn ();
|
||||||
|
abstract public void LogOut ();
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
abstract public class EnterpriseServicesSecurity {
|
||||||
|
abstract public void LogOn ();
|
||||||
|
abstract public void LogOff ();
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Naming.UseSingularNameInEnumsUnlessAreFlagsRule">
|
||||||
|
<summary>
|
||||||
|
The rule is used for ensure that the name of enumerations are in singular form unless
|
||||||
|
the enumeration is used as flags, i.e. decorated with the <c>[Flags]</c> attribute.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public enum MyCustomValues {
|
||||||
|
Foo,
|
||||||
|
Bar
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (singular):
|
||||||
|
<code>
|
||||||
|
public enum MyCustomValue {
|
||||||
|
Foo,
|
||||||
|
Bar
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (flags):
|
||||||
|
<code>
|
||||||
|
[Flags]
|
||||||
|
public enum MyCustomValues {
|
||||||
|
Foo,
|
||||||
|
Bar,
|
||||||
|
AllValues = Foo | Bar
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
|
</doc>
|
Двоичный файл не отображается.
Двоичный файл не отображается.
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -0,0 +1,190 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<doc>
|
||||||
|
<assembly>
|
||||||
|
<name>Gendarme.Rules.Portability</name>
|
||||||
|
</assembly>
|
||||||
|
<members>
|
||||||
|
<member name="T:Gendarme.Rules.Portability.DoNotHardcodePathsRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for strings that contain valid paths, either under Unix or
|
||||||
|
Windows file systems. Path literals are often not portable across
|
||||||
|
operating systems (e.g. different path separators). To ensure correct cross-platform
|
||||||
|
functionality they should be replaced by calls to <c>Path.Combine</c> and/or
|
||||||
|
<c>Environment.GetFolderPath</c>.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
void ReadConfig ()
|
||||||
|
{
|
||||||
|
using (FileStream fs = File.Open ("~/.local/share/myapp/user.config")) {
|
||||||
|
// read configuration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
void ReadConfig ()
|
||||||
|
{
|
||||||
|
string config_file = Environment.GetFolderPath (SpecialFolder.LocalApplicationData);
|
||||||
|
config_file = Path.Combine (Path.Combine (config_file, "myapp"), "user.config");
|
||||||
|
using (FileStream fs = File.Open (config_file)) {
|
||||||
|
// read configuration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Portability.ExitCodeIsLimitedOnUnixRule">
|
||||||
|
<summary>
|
||||||
|
This rule applies to all executable (i.e. EXE) assemblies. Something that many Windows
|
||||||
|
developers might not be aware of is that on Unix systems, process exit code must be
|
||||||
|
between zero and 255, unlike in Windows where it can be any valid integer value.
|
||||||
|
This rule warns if the returned value might be out of range either by:
|
||||||
|
<list type="bullet"><item><description>returning an unknown value from <c>int Main()</c>;</description></item><item><description>setting the <c>Environment.ExitCode</c> property; or</description></item><item><description>calling <c>Environment.Exit(exitCode)</c> method.</description></item></list>
|
||||||
|
An error is reported in case a number which is definitely out of range is returned
|
||||||
|
as an exit code.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
class MainClass {
|
||||||
|
static int Main ()
|
||||||
|
{
|
||||||
|
Environment.ExitCode = 1000;
|
||||||
|
Environment.Exit (512);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
class MainClass {
|
||||||
|
static int Main ()
|
||||||
|
{
|
||||||
|
Environment.ExitCode = 42;
|
||||||
|
Environment.Exit (100);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Portability.FeatureRequiresRootPrivilegeOnUnixRule">
|
||||||
|
<summary>
|
||||||
|
This rule fires if a feature is used which is, by default, restricted under Unix.
|
||||||
|
<list type="bullet"><item><description><c>System.Net.NetworkInformation.Ping</c>: This type can only be used
|
||||||
|
by root on Unix systems. As an alternative you can execute the ping command and
|
||||||
|
parse its result.</description></item><item><description><c>System.Diagnostics.Process</c>: The PriorityClass property can only
|
||||||
|
be set to <c>Normal</c> by non-root users. To avoid this problem you can do a
|
||||||
|
platform check before assigning a priority.</description></item></list></summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
process.PriorityClass = ProcessPriorityClass.AboveNormal;
|
||||||
|
process.Start ();
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
if (Environment.OSVersion.Platform != PlatformID.Unix) {
|
||||||
|
process.PriorityClass = ProcessPriorityClass.AboveNormal;
|
||||||
|
}
|
||||||
|
process.Start ();
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:MoMA.Analyzer.MoMAWebService.MoMASubmit">
|
||||||
|
<remarks />
|
||||||
|
</member>
|
||||||
|
<member name="M:MoMA.Analyzer.MoMAWebService.MoMASubmit.#ctor">
|
||||||
|
<remarks />
|
||||||
|
</member>
|
||||||
|
<member name="E:MoMA.Analyzer.MoMAWebService.MoMASubmit.SubmitResultsCompleted">
|
||||||
|
<remarks />
|
||||||
|
</member>
|
||||||
|
<member name="E:MoMA.Analyzer.MoMAWebService.MoMASubmit.GetLatestDefinitionsVersionCompleted">
|
||||||
|
<remarks />
|
||||||
|
</member>
|
||||||
|
<member name="M:MoMA.Analyzer.MoMAWebService.MoMASubmit.SubmitResults(System.String)">
|
||||||
|
<remarks />
|
||||||
|
</member>
|
||||||
|
<member name="M:MoMA.Analyzer.MoMAWebService.MoMASubmit.SubmitResultsAsync(System.String)">
|
||||||
|
<remarks />
|
||||||
|
</member>
|
||||||
|
<member name="M:MoMA.Analyzer.MoMAWebService.MoMASubmit.SubmitResultsAsync(System.String,System.Object)">
|
||||||
|
<remarks />
|
||||||
|
</member>
|
||||||
|
<member name="M:MoMA.Analyzer.MoMAWebService.MoMASubmit.GetLatestDefinitionsVersion">
|
||||||
|
<remarks />
|
||||||
|
</member>
|
||||||
|
<member name="M:MoMA.Analyzer.MoMAWebService.MoMASubmit.GetLatestDefinitionsVersionAsync">
|
||||||
|
<remarks />
|
||||||
|
</member>
|
||||||
|
<member name="M:MoMA.Analyzer.MoMAWebService.MoMASubmit.GetLatestDefinitionsVersionAsync(System.Object)">
|
||||||
|
<remarks />
|
||||||
|
</member>
|
||||||
|
<member name="M:MoMA.Analyzer.MoMAWebService.MoMASubmit.CancelAsync(System.Object)">
|
||||||
|
<remarks />
|
||||||
|
</member>
|
||||||
|
<member name="T:MoMA.Analyzer.MoMAWebService.SubmitResultsCompletedEventHandler">
|
||||||
|
<remarks />
|
||||||
|
</member>
|
||||||
|
<member name="T:MoMA.Analyzer.MoMAWebService.SubmitResultsCompletedEventArgs">
|
||||||
|
<remarks />
|
||||||
|
</member>
|
||||||
|
<member name="P:MoMA.Analyzer.MoMAWebService.SubmitResultsCompletedEventArgs.Result">
|
||||||
|
<remarks />
|
||||||
|
</member>
|
||||||
|
<member name="T:MoMA.Analyzer.MoMAWebService.GetLatestDefinitionsVersionCompletedEventHandler">
|
||||||
|
<remarks />
|
||||||
|
</member>
|
||||||
|
<member name="T:MoMA.Analyzer.MoMAWebService.GetLatestDefinitionsVersionCompletedEventArgs">
|
||||||
|
<remarks />
|
||||||
|
</member>
|
||||||
|
<member name="P:MoMA.Analyzer.MoMAWebService.GetLatestDefinitionsVersionCompletedEventArgs.Result">
|
||||||
|
<remarks />
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Portability.MonoCompatibilityReviewRule">
|
||||||
|
<summary>
|
||||||
|
This rule will fire if one of the assemblies being checked contains a call to a .NET
|
||||||
|
method which is either not implemented on Mono or partially implemented. It does
|
||||||
|
this by downloading a MoMA definitions file under <c>~/.local/share/Gendarme/</c> (on UNIX)
|
||||||
|
or <c>C:\Documents and Settings\{username}\Local Settings\Application Data\Gendarme</c>
|
||||||
|
(on Windows) and checking for calls to the methods therein. The rule will work without
|
||||||
|
MoMA but if it does fire it may be useful to download and run MoMA.
|
||||||
|
By default the rule will use the latest local version available. This can be overriden to use a
|
||||||
|
specific, local, version if you want to review compatibility against a specific Mono version.
|
||||||
|
You can also manually remove them, now and then, to ensure you are using the latest version.
|
||||||
|
Also upgrading Gendarme will try to download a newer version of the definitions files.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:Gendarme.Rules.Portability.MonoCompatibilityReviewRule.Version">
|
||||||
|
<summary>
|
||||||
|
The version of Mono against which you wish to review compatibility.
|
||||||
|
You need to have this version of the definitions file downloaded in order to use it.
|
||||||
|
This is useful if you want to upgrade Gendarme but still want to test compatibility
|
||||||
|
against an older version of Mono.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Portability.NewLineLiteralRule">
|
||||||
|
<summary>
|
||||||
|
This rule warns if methods, including properties, are using the literal
|
||||||
|
<c>\r</c> and/or <c>\n</c> for new lines. This isn't portable across operating systems.
|
||||||
|
To ensure correct cross-platform functionality they should be replaced by
|
||||||
|
<c>System.Environment.NewLine</c>.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
Console.WriteLine ("Hello,\nYou should be using Gendarme!");
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
Console.WriteLine ("Hello,{0}You must be using Gendarme!", Environment.NewLine);
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
|
</doc>
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -0,0 +1,216 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<doc>
|
||||||
|
<assembly>
|
||||||
|
<name>Gendarme.Rules.Security.Cas</name>
|
||||||
|
</assembly>
|
||||||
|
<members>
|
||||||
|
<member name="T:Gendarme.Rules.Security.Cas.AddMissingTypeInheritanceDemandRule">
|
||||||
|
<summary>
|
||||||
|
The rule checks for types that are not <c>sealed</c> but have a <c>LinkDemand</c>.
|
||||||
|
In this case the type should also have an <c>InheritanceDemand</c> for the same
|
||||||
|
permissions. An alternative is to seal the type.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[SecurityPermission (SecurityAction.LinkDemand, ControlThread = true)]
|
||||||
|
public class Bad {
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (InheritanceDemand):
|
||||||
|
<code>
|
||||||
|
[SecurityPermission (SecurityAction.LinkDemand, ControlThread = true)]
|
||||||
|
[SecurityPermission (SecurityAction.InheritanceDemand, ControlThread = true)]
|
||||||
|
public class Correct {
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (sealed):
|
||||||
|
<code>
|
||||||
|
[SecurityPermission (SecurityAction.LinkDemand, ControlThread = true)]
|
||||||
|
public sealed class Correct {
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>Before Gendarme 2.2 this rule was part of Gendarme.Rules.Security and named TypeLinkDemandRule.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Security.Cas.DoNotExposeFieldsInSecuredTypeRule">
|
||||||
|
<summary>
|
||||||
|
The rule checks for types that are secured by <c>Demand</c> or <c>LinkDemand</c>
|
||||||
|
but also expose visible fields. Access to these fields is not covered by the
|
||||||
|
declarative demands, opening potential security holes.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[SecurityPermission (SecurityAction.LinkDemand, ControlThread = true)]
|
||||||
|
public class Bad {
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (InheritanceDemand):
|
||||||
|
<code>
|
||||||
|
[SecurityPermission (SecurityAction.LinkDemand, ControlThread = true)]
|
||||||
|
[SecurityPermission (SecurityAction.InheritanceDemand, ControlThread = true)]
|
||||||
|
public class Correct {
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (sealed):
|
||||||
|
<code>
|
||||||
|
[SecurityPermission (SecurityAction.LinkDemand, ControlThread = true)]
|
||||||
|
public sealed class Correct {
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>Before Gendarme 2.2 this rule was part of Gendarme.Rules.Security and named TypeExposeFieldsRule.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Security.Cas.DoNotExposeMethodsProtectedByLinkDemandRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for visible methods that are less protected (i.e. lower security
|
||||||
|
requirements) than the method they call. If the called methods are protected by a
|
||||||
|
<c>LinkDemand</c> then the caller can be used to bypass security checks.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public class BaseClass {
|
||||||
|
[SecurityPermission (SecurityAction.LinkDemand, Unrestricted = true)]
|
||||||
|
public virtual void VirtualMethod ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class Class : BaseClass {
|
||||||
|
// bad since a caller with only ControlAppDomain will be able to call the base method
|
||||||
|
[SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
|
||||||
|
public override void VirtualMethod ()
|
||||||
|
{
|
||||||
|
base.VirtualMethod ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (InheritanceDemand):
|
||||||
|
<code>
|
||||||
|
public class BaseClass {
|
||||||
|
[SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
|
||||||
|
public virtual void VirtualMethod ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class Class : BaseClass {
|
||||||
|
// ok since this permission cover the base class permission
|
||||||
|
[SecurityPermission (SecurityAction.LinkDemand, Unrestricted = true)]
|
||||||
|
public override void VirtualMethod ()
|
||||||
|
{
|
||||||
|
base.VirtualMethod ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>Before Gendarme 2.2 this rule was part of Gendarme.Rules.Security and named MethodCallWithSubsetLinkDemandRule.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Security.Cas.DoNotReduceTypeSecurityOnMethodsRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for types that have declarative security permission which aren't a
|
||||||
|
subset of the security permission of some of their methods.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[SecurityPermission (SecurityAction.Assert, ControlThread = true)]
|
||||||
|
public class NotSubset {
|
||||||
|
[EnvironmentPermission (SecurityAction.Assert, Unrestricted = true)]
|
||||||
|
public void Method ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
[SecurityPermission (SecurityAction.Assert, ControlThread = true)]
|
||||||
|
public class Subset {
|
||||||
|
[SecurityPermission (SecurityAction.Assert, Unrestricted = true)]
|
||||||
|
public void Method ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>Before Gendarme 2.2 this rule was part of Gendarme.Rules.Security and named TypeIsNotSubsetOfMethodSecurityRule.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Security.Cas.ReviewSealedTypeWithInheritanceDemandRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for sealed types that have <c>InheritanceDemand</c> declarative
|
||||||
|
security applied to them. Since those types cannot be inherited from the
|
||||||
|
<c>InheritanceDemand</c> will never be executed by the runtime. Check if the permission
|
||||||
|
is required and, if so, change the <c>SecurityAction</c> to the correct one. Otherwise
|
||||||
|
remove the permission.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[SecurityPermission (SecurityAction.InheritanceDemand, Unrestricted = true)]
|
||||||
|
public sealed class Bad {
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (non sealed):
|
||||||
|
<code>
|
||||||
|
[SecurityPermission (SecurityAction.InheritanceDemand, Unrestricted = true)]
|
||||||
|
public class Good {
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (LinkDemand):
|
||||||
|
<code>
|
||||||
|
[SecurityPermission (SecurityAction.LinkDemand, Unrestricted = true)]
|
||||||
|
public sealed class Good {
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>Before Gendarme 2.2 this rule was part of Gendarme.Rules.Security and named SealedTypeWithInheritanceDemandRule.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Security.Cas.ReviewSuppressUnmanagedCodeSecurityUsageRule">
|
||||||
|
<summary>
|
||||||
|
This rule fires if a type or method is decorated with the <c>[SuppressUnmanagedCodeSecurity]</c>
|
||||||
|
attribute. This attribute reduces the security checks done when executing unmanaged code and its
|
||||||
|
usage should be reviewed to confirm that no exploitable security holes are present.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Example:
|
||||||
|
<code>
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
public class Safe {
|
||||||
|
[DllImport ("User32.dll")]
|
||||||
|
static extern Boolean MessageBeep (UInt32 beepType);
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This is an Audit rule. As such it does not check for valid or invalid patterns but warns about a specific problem that needs to be reviewed by someone.</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Security.Cas.SecureGetObjectDataOverridesRule">
|
||||||
|
<summary>
|
||||||
|
This rule fires if a type implements <c>System.Runtime.Serialization.ISerializable</c>
|
||||||
|
but the <c>GetObjectData</c> method is not protected with a <c>Demand</c> or
|
||||||
|
<c>LinkDemand</c> for <c>SerializationFormatter</c>.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public class Bad : ISerializable {
|
||||||
|
public override void GetObjectData (SerializationInfo info, StreamingContext context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public class Good : ISerializable {
|
||||||
|
[SecurityPermission (SecurityAction.LinkDemand, SerializationFormatter = true)]
|
||||||
|
public override void GetObjectData (SerializationInfo info, StreamingContext context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>Before Gendarme 2.2 this rule was part of Gendarme.Rules.Security.</remarks>
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
|
</doc>
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -0,0 +1,128 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<doc>
|
||||||
|
<assembly>
|
||||||
|
<name>Gendarme.Rules.Security</name>
|
||||||
|
</assembly>
|
||||||
|
<members>
|
||||||
|
<member name="T:Gendarme.Rules.Security.ArrayFieldsShouldNotBeReadOnlyRule">
|
||||||
|
<summary>
|
||||||
|
This rule warns if a type declares a public <c>readonly</c> array field.
|
||||||
|
Marking a field <c>readonly</c> only prevents the field from being assigned
|
||||||
|
a different value, the object itself can still be changed. This means, that
|
||||||
|
the elements inside the array can still be changed.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
class Bad {
|
||||||
|
public readonly string[] Array = new string[] { "A", "B" };
|
||||||
|
}
|
||||||
|
HasPublicReadonlyArray obj = HasPublicReadonlyArray ();
|
||||||
|
obj.Array[0] = "B"; // valid
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
class Good {
|
||||||
|
private readonly string[] array = new string[] { "A", "B" };
|
||||||
|
public string[] GetArray ()
|
||||||
|
{
|
||||||
|
return (string []) array.Clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
string[] obj = new HasPublicReadonlyArray ().GetArray ();
|
||||||
|
obj [0] = "B"; // valid, but has no effect on other users
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Security.DoNotShortCircuitCertificateCheckRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for methods that implements pass-through certificate checks.
|
||||||
|
I.e. methods that override the framework decision about a certificate validity
|
||||||
|
without checking anything specific about the supplied certificate or error code.
|
||||||
|
Protocols like TLS/SSL are only secure if the certificates are used correctly.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example (ICertificatePolicy):
|
||||||
|
<code>
|
||||||
|
public class AcceptEverythingCertificatePolicy : ICertificatePolicy {
|
||||||
|
public bool CheckValidationResult (ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem)
|
||||||
|
{
|
||||||
|
// this accepts everything making it easy for MITM
|
||||||
|
// (Man-in-the-middle) attacks
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (ICertificatePolicy):
|
||||||
|
<code>
|
||||||
|
public class AllowSpecificCertificatePolicy : ICertificatePolicy {
|
||||||
|
public bool CheckValidationResult (ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem)
|
||||||
|
{
|
||||||
|
// this accept only a specific certificate, even if others would be ok
|
||||||
|
return (certificate.GetCertHashString () == "D62F48D013EE7FB58B79074512670D9C5B3A5DA9");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Bad example (RemoteCertificateValidationCallback):
|
||||||
|
<code>
|
||||||
|
public bool CertificateValidationCallback (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
|
||||||
|
{
|
||||||
|
// this accepts everything making it easy for MITM
|
||||||
|
// (Man-in-the-middle) attacks
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
SslStream ssl = new SslStream (stream, false, new RemoteCertificateValidationCallback (CertificateValidationCallback), null);
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (RemoteCertificateValidationCallback):
|
||||||
|
<code>
|
||||||
|
public bool CertificateValidationCallback (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
|
||||||
|
{
|
||||||
|
// this accept only a specific certificate, even if others would be ok
|
||||||
|
return (certificate.GetCertHashString () == "D62F48D013EE7FB58B79074512670D9C5B3A5DA9");
|
||||||
|
}
|
||||||
|
SslStream ssl = new SslStream (stream, false, new RemoteCertificateValidationCallback (CertificateValidationCallback), null);
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.4</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Security.NativeFieldsShouldNotBeVisibleRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks if a class exposes native fields. Native fields should not
|
||||||
|
be public because you lose control over their lifetime (other code could free
|
||||||
|
the memory or use it after it has been freed).
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public class HasPublicNativeField {
|
||||||
|
public IntPtr NativeField;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (hide):
|
||||||
|
<code>
|
||||||
|
class HasPrivateNativeField {
|
||||||
|
private IntPtr NativeField;
|
||||||
|
public void DoSomethingWithNativeField ();
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (read-only):
|
||||||
|
<code>
|
||||||
|
class HasReadOnlyNativeField {
|
||||||
|
public readonly IntPtr NativeField;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Security.StaticConstructorsShouldBePrivateRule">
|
||||||
|
<summary>
|
||||||
|
This rule will fire if a type's static constructor is not private. This is a problem
|
||||||
|
because the static constructor is meant to be called by the runtime but if it is
|
||||||
|
not private then other code may call it as well which may lead to security
|
||||||
|
vulnerabilities. Note that C# and VB.NET enforce this rule.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
|
</doc>
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -0,0 +1,326 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<doc>
|
||||||
|
<assembly>
|
||||||
|
<name>Gendarme.Rules.Serialization</name>
|
||||||
|
</assembly>
|
||||||
|
<members>
|
||||||
|
<member name="T:Gendarme.Rules.Serialization.CallBaseMethodsOnISerializableTypesRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks types that implement the <c>System.ISerializable</c> interface
|
||||||
|
and fires if either the serialization constructor or the <c>GetObjectData</c>
|
||||||
|
method does not call it's <c>base</c> type, potentially breaking the serialization
|
||||||
|
process.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[Serializable]
|
||||||
|
public class Base : ISerializable {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
[Serializable]
|
||||||
|
public class Bad : Base {
|
||||||
|
int value;
|
||||||
|
protected BadDerived (SerializationInfo info, StreamingContext context)
|
||||||
|
{
|
||||||
|
value = info.GetInt32 ("value");
|
||||||
|
}
|
||||||
|
public override void GetObjectData (SerializationInfo info, StreamingContext context)
|
||||||
|
{
|
||||||
|
info.AddValue ("value", value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
[Serializable]
|
||||||
|
public class Base : ISerializable {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
[Serializable]
|
||||||
|
public class Good : Base {
|
||||||
|
int value;
|
||||||
|
protected BadDerived (SerializationInfo info, StreamingContext context) : base (info, context)
|
||||||
|
{
|
||||||
|
value = info.GetInt32 ("value");
|
||||||
|
}
|
||||||
|
public override void GetObjectData (SerializationInfo info, StreamingContext context)
|
||||||
|
{
|
||||||
|
info.AddValue ("value", value);
|
||||||
|
base.GetObjectData (info, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.2</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Serialization.DeserializeOptionalFieldRule">
|
||||||
|
<summary>
|
||||||
|
This rule will fire if a type has fields marked with <c>[OptionalField]</c>, but does
|
||||||
|
not have methods decorated with the <c>[OnDeserialized]</c> or <c>[OnDeserializing]</c>
|
||||||
|
attributes. This is a problem because the binary deserializer does not actually construct
|
||||||
|
objects (it uses <c>System.Runtime.Serialization.FormatterServices.GetUninitializedObject</c>
|
||||||
|
instead). So, if binary deserialization is used the optional field(s) will be zeroed instead
|
||||||
|
of properly initialized.
|
||||||
|
This rule only applies to assemblies compiled with the .NET framework version 2.0
|
||||||
|
(or later).
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[Serializable]
|
||||||
|
public class ClassWithOptionalField {
|
||||||
|
[OptionalField]
|
||||||
|
private int optional;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
[Serializable]
|
||||||
|
public class ClassWithOptionalField {
|
||||||
|
// Normally the (compiler generated) default constructor will
|
||||||
|
// initialize this. The default constructor will be called by the
|
||||||
|
// XML and Soap deserializers, but not the binary serializer.
|
||||||
|
[OptionalField]
|
||||||
|
private int optional = 1;
|
||||||
|
// This will be called immediately after the object is
|
||||||
|
// deserialized.
|
||||||
|
[OnDeserializing]
|
||||||
|
private void OnDeserializing (StreamingContext context)
|
||||||
|
{
|
||||||
|
optional = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Serialization.ImplementISerializableCorrectlyRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for types that implement <c>ISerializable</c>. Such types
|
||||||
|
serialize their data by implementing <c>GetObjectData</c>. This
|
||||||
|
rule verifies that every instance field, not decorated with the <c>[NonSerialized]</c>
|
||||||
|
attribute is serialized by the <c>GetObjectData</c> method. This rule will also warn
|
||||||
|
if the type is unsealed and the <c>GetObjectData</c> is not <c>virtual</c>.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[Serializable]
|
||||||
|
public class Bad : ISerializable {
|
||||||
|
int foo;
|
||||||
|
string bar;
|
||||||
|
protected Bad (SerializationInfo info, StreamingContext context)
|
||||||
|
{
|
||||||
|
foo = info.GetInt32 ("foo");
|
||||||
|
}
|
||||||
|
// extensibility is limited since GetObjectData is not virtual:
|
||||||
|
// any type inheriting won't be able to serialized additional fields
|
||||||
|
public void GetObjectData (SerializationInfo info, StreamingContext context)
|
||||||
|
{
|
||||||
|
info.AddValue ("foo", foo);
|
||||||
|
// 'bar' is not serialized, if not needed then the field should
|
||||||
|
// be decorated with [NotSerialized]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (virtual and not serialized):
|
||||||
|
<code>
|
||||||
|
[Serializable]
|
||||||
|
public class Good : ISerializable {
|
||||||
|
int foo;
|
||||||
|
[NotSerialized]
|
||||||
|
string bar;
|
||||||
|
protected Good (SerializationInfo info, StreamingContext context)
|
||||||
|
{
|
||||||
|
foo = info.GetInt32 ("foo");
|
||||||
|
}
|
||||||
|
public virtual void GetObjectData (SerializationInfo info, StreamingContext context)
|
||||||
|
{
|
||||||
|
info.AddValue ("foo", foo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (sealed type and serialized):
|
||||||
|
<code>
|
||||||
|
[Serializable]
|
||||||
|
public sealed class Good : ISerializable {
|
||||||
|
int foo;
|
||||||
|
string bar;
|
||||||
|
protected Good (SerializationInfo info, StreamingContext context)
|
||||||
|
{
|
||||||
|
foo = info.GetInt32 ("foo");
|
||||||
|
}
|
||||||
|
public void GetObjectData (SerializationInfo info, StreamingContext context)
|
||||||
|
{
|
||||||
|
info.AddValue ("foo", foo);
|
||||||
|
info.AddValue ("bar", bar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Serialization.MarkAllNonSerializableFieldsRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for serializable types, i.e. decorated with the <c>[Serializable]</c>
|
||||||
|
attribute, and checks to see if all its fields are serializable as well. If not the rule will
|
||||||
|
fire unless the field is decorated with the <c>[NonSerialized]</c> attribute.
|
||||||
|
The rule will also warn if the field type is an interface as it is not possible,
|
||||||
|
before execution time, to know for certain if the type can be serialized or not.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
class NonSerializableClass {
|
||||||
|
}
|
||||||
|
[Serializable]
|
||||||
|
class SerializableClass {
|
||||||
|
NonSerializableClass field;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
class NonSerializableClass {
|
||||||
|
}
|
||||||
|
[Serializable]
|
||||||
|
class SerializableClass {
|
||||||
|
[NonSerialized]
|
||||||
|
NonSerializableClass field;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Serialization.MarkEnumerationsAsSerializableRule">
|
||||||
|
<summary>
|
||||||
|
This rule warns when it founds an <c>enum</c> that is not decorated with
|
||||||
|
a <c>[Serializable]</c> attribute. Enums, even without the attribute,
|
||||||
|
are always serializable. Marking them as such makes the source code more readable.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public enum Colors {
|
||||||
|
Black,
|
||||||
|
White
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
[Serializable]
|
||||||
|
public enum Colors {
|
||||||
|
Black,
|
||||||
|
White
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.2</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Serialization.MissingSerializableAttributeOnISerializableTypeRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for types that implement <c>System.ISerializable</c> but are
|
||||||
|
not decorated with the <c>[Serializable]</c> attribute. Implementing
|
||||||
|
<c>System.ISerializable</c> is not enough to make a class serializable as this
|
||||||
|
interface only gives you more control over the basic serialization process.
|
||||||
|
In order for the runtime to know your type is serializable it must have the
|
||||||
|
<c>[Serializable]</c> attribute.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
// this type cannot be serialized by the runtime
|
||||||
|
public class Bad : ISerializable {
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
[Serializable]
|
||||||
|
public class Good : ISerializable {
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Serialization.MissingSerializationConstructorRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for types that implement <c>System.ISerializable</c> but don't provide a
|
||||||
|
serialization constructor. The constructor is required in order to make the type
|
||||||
|
serializeable but cannot be enforced by the interface.
|
||||||
|
The serialization constructor should be <c>private</c> for <c>sealed</c> types and
|
||||||
|
<c>protected</c> for unsealed types.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[Serializable]
|
||||||
|
public class Bad : ISerializable {
|
||||||
|
public void GetObjectData (SerializationInfo info, StreamingContext context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example (sealed):
|
||||||
|
<code>
|
||||||
|
[Serializable]
|
||||||
|
public sealed class Good : ISerializable {
|
||||||
|
private ClassWithConstructor (SerializationInfo info, StreamingContext context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public void GetObjectData (SerializationInfo info, StreamingContext context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
[Serializable]
|
||||||
|
public class Good : ISerializable {
|
||||||
|
protected ClassWithConstructor (SerializationInfo info, StreamingContext context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public void GetObjectData (SerializationInfo info, StreamingContext context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Serialization.UseCorrectSignatureForSerializationMethodsRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for methods which use the serialization attributes:
|
||||||
|
<c>[OnSerializing, OnDeserializing, OnSerialized, OnDeserialized]</c>. You must
|
||||||
|
ensure that these methods have the correct signature. They should be <c>private</c>,
|
||||||
|
return <c>void</c> and have a single parameter of type <c>StreamingContext</c>.
|
||||||
|
Failure to have the right signature can, in some circumstances, make your assembly
|
||||||
|
unusable at runtime.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
[Serializable]
|
||||||
|
public class Bad {
|
||||||
|
[OnSerializing]
|
||||||
|
public bool Serializing (StreamingContext context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
[Serializable]
|
||||||
|
public class BadClass {
|
||||||
|
[OnSerializing]
|
||||||
|
private void Serializing (StreamingContext context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.0</remarks>
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
|
</doc>
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -0,0 +1,415 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<doc>
|
||||||
|
<assembly>
|
||||||
|
<name>Gendarme.Rules.Smells</name>
|
||||||
|
</assembly>
|
||||||
|
<members>
|
||||||
|
<member name="T:Gendarme.Rules.Smells.AvoidCodeDuplicatedInSameClassRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for duplicated code in the same class.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public class MyClass {
|
||||||
|
private IList myList;
|
||||||
|
public MyClass () {
|
||||||
|
myList = new ArrayList ();
|
||||||
|
myList.Add ("Foo");
|
||||||
|
myList.Add ("Bar");
|
||||||
|
myList.Add ("Baz");
|
||||||
|
}
|
||||||
|
public void MakeStuff () {
|
||||||
|
foreach (string value in myList) {
|
||||||
|
Console.WriteLine (value);
|
||||||
|
}
|
||||||
|
myList.Add ("FooReplied");
|
||||||
|
}
|
||||||
|
public void MakeMoreStuff () {
|
||||||
|
foreach (string value in myList) {
|
||||||
|
Console.WriteLine (value);
|
||||||
|
}
|
||||||
|
myList.Remove ("FooReplied");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public class MyClass {
|
||||||
|
private IList myList;
|
||||||
|
public MyClass () {
|
||||||
|
myList = new ArrayList ();
|
||||||
|
myList.Add ("Foo");
|
||||||
|
myList.Add ("Bar");
|
||||||
|
myList.Add ("Baz");
|
||||||
|
}
|
||||||
|
private void PrintValuesInList () {
|
||||||
|
foreach (string value in myList) {
|
||||||
|
Console.WriteLine (value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void MakeStuff () {
|
||||||
|
PrintValuesInList ();
|
||||||
|
myList.Add ("FooReplied");
|
||||||
|
}
|
||||||
|
public void MakeMoreStuff () {
|
||||||
|
PrintValuesInList ();
|
||||||
|
myList.Remove ("FooReplied");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Smells.AvoidCodeDuplicatedInSiblingClassesRule">
|
||||||
|
<summary>
|
||||||
|
This rule looks for code duplicated in sibling subclasses.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public class BaseClassWithCodeDuplicated {
|
||||||
|
protected IList list;
|
||||||
|
}
|
||||||
|
public class OverriderClassWithCodeDuplicated : BaseClassWithCodeDuplicated {
|
||||||
|
public void CodeDuplicated ()
|
||||||
|
{
|
||||||
|
foreach (int i in list) {
|
||||||
|
Console.WriteLine (i);
|
||||||
|
}
|
||||||
|
list.Add (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class OtherOverriderWithCodeDuplicated : BaseClassWithCodeDuplicated {
|
||||||
|
public void OtherMethod ()
|
||||||
|
{
|
||||||
|
foreach (int i in list) {
|
||||||
|
Console.WriteLine (i);
|
||||||
|
}
|
||||||
|
list.Remove (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public class BaseClassWithoutCodeDuplicated {
|
||||||
|
protected IList list;
|
||||||
|
protected void PrintValuesInList ()
|
||||||
|
{
|
||||||
|
foreach (int i in list) {
|
||||||
|
Console.WriteLine (i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class OverriderClassWithoutCodeDuplicated : BaseClassWithoutCodeDuplicated {
|
||||||
|
public void SomeCode ()
|
||||||
|
{
|
||||||
|
PrintValuesInList ();
|
||||||
|
list.Add (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class OtherOverriderWithoutCodeDuplicated : BaseClassWithoutCodeDuplicated {
|
||||||
|
public void MoreCode ()
|
||||||
|
{
|
||||||
|
PrintValuesInList ();
|
||||||
|
list.Remove (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Smells.AvoidLargeClassesRule">
|
||||||
|
<summary>
|
||||||
|
This rule allows developers to measure the classes size. When a
|
||||||
|
class is trying to doing a lot of work, then you probabily have
|
||||||
|
the Large Class smell.
|
||||||
|
This rule will fire if a type contains too many fields (over 25 by default) or
|
||||||
|
has fields with common prefixes. If the rule does fire then the type should
|
||||||
|
be reviewed to see if new classes should be extracted from it.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public class MyClass {
|
||||||
|
int x, x1, x2, x3;
|
||||||
|
string s, s1, s2, s3;
|
||||||
|
DateTime bar, bar1, bar2;
|
||||||
|
string[] strings, strings1;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public class MyClass {
|
||||||
|
int x;
|
||||||
|
string s;
|
||||||
|
DateTime bar;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Smells.AvoidLongMethodsRule">
|
||||||
|
<summary>
|
||||||
|
This rule allows developers to measure the method size. The short sized
|
||||||
|
methods allows you to maintain your code better, if you have long sized
|
||||||
|
methods perhaps you have the Long Method smell.
|
||||||
|
The rule will skip some well known methods, because they are autogenerated:
|
||||||
|
<list type="bullet"><item><description><c>Gtk.Bin::Build ()</c></description></item><item><description><c>Gtk.Window::Build ()</c></description></item><item><description><c>Gtk.Dialog::Build ()</c></description></item><item><description><c>System.Windows.Forms::InitializeComponents ()</c></description></item><item><description><c>System.Workflow.Activities.StateMachineWorkflowActivity::InitializeComponents ()</c></description></item><item><description><c>System.Workflow.Activities.SequentialWorkflowActivity::InitializeComponents ()</c></description></item><item><description><c>System.Windows.Controls.UserControl::InitializeComponents ()</c></description></item></list>
|
||||||
|
This will work for classes that extend those types.
|
||||||
|
If debugging symbols (e.g. Mono .mdb or MS .pdb) are available then the rule
|
||||||
|
will compute the number of logical source line of code (SLOC). This number
|
||||||
|
represent the lines where 'SequencePoint' are present in the code. By
|
||||||
|
default the maximum SLOC is defined to 40 lines.
|
||||||
|
Otherwise the rule falls back onto an IL-SLOC approximation. It's quite
|
||||||
|
hard to determine how many SLOC exists based on the IL (e.g. LINQ). The metric
|
||||||
|
being used is based on a screen (1024 x 768) full of source code where the
|
||||||
|
number of IL instructions were counted. By default the maximum number of IL
|
||||||
|
instructions is defined to be 165.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public void LongMethod ()
|
||||||
|
{
|
||||||
|
Console.WriteLine ("I'm writting a test, and I will fill a screen with some useless code");
|
||||||
|
IList list = new ArrayList ();
|
||||||
|
list.Add ("Foo");
|
||||||
|
list.Add (4);
|
||||||
|
list.Add (6);
|
||||||
|
IEnumerator listEnumerator = list.GetEnumerator ();
|
||||||
|
while (listEnumerator.MoveNext ()) {
|
||||||
|
Console.WriteLine (listEnumerator.Current);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
list.Add ("Bar");
|
||||||
|
list.Add ('a');
|
||||||
|
}
|
||||||
|
catch (NotSupportedException exception) {
|
||||||
|
Console.WriteLine (exception.Message);
|
||||||
|
Console.WriteLine (exception);
|
||||||
|
}
|
||||||
|
foreach (object value in list) {
|
||||||
|
Console.Write (value);
|
||||||
|
Console.Write (Environment.NewLine);
|
||||||
|
}
|
||||||
|
int x = 0;
|
||||||
|
for (int i = 0; i < 100; i++) {
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
Console.WriteLine (x);
|
||||||
|
string useless = "Useless String";
|
||||||
|
if (useless.Equals ("Other useless")) {
|
||||||
|
useless = String.Empty;
|
||||||
|
Console.WriteLine ("Other useless string");
|
||||||
|
}
|
||||||
|
useless = String.Concat (useless," 1");
|
||||||
|
for (int j = 0; j < useless.Length; j++) {
|
||||||
|
if (useless[j] == 'u') {
|
||||||
|
Console.WriteLine ("I have detected an u char");
|
||||||
|
} else {
|
||||||
|
Console.WriteLine ("I have detected an useless char");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
foreach (string environmentVariable in Environment.GetEnvironmentVariables ().Keys) {
|
||||||
|
Console.WriteLine (environmentVariable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (System.Security.SecurityException exception) {
|
||||||
|
Console.WriteLine (exception.Message);
|
||||||
|
Console.WriteLine (exception);
|
||||||
|
}
|
||||||
|
Console.WriteLine ("I will add more useless code !!");
|
||||||
|
try {
|
||||||
|
if (!(File.Exists ("foo.txt"))) {
|
||||||
|
File.Create ("foo.txt");
|
||||||
|
File.Delete ("foo.txt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException exception) {
|
||||||
|
Console.WriteLine (exception.Message);
|
||||||
|
Console.WriteLine (exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public void ShortMethod ()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
foreach (string environmentVariable in Environment.GetEnvironmentVariables ().Keys) {
|
||||||
|
Console.WriteLine (environmentVariable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (System.Security.SecurityException exception) {
|
||||||
|
Console.WriteLine (exception.Message);
|
||||||
|
Console.WriteLine (exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Smells.AvoidLongParameterListsRule">
|
||||||
|
<summary>
|
||||||
|
This rule allows developers to measure the parameter list size in a method.
|
||||||
|
If you have methods with a lot of parameters, perhaps you have a Long
|
||||||
|
Parameter List smell.
|
||||||
|
This rule counts the method's parameters, and compares it against a maximum value.
|
||||||
|
If you have an overloaded method, then the rule will get the shortest overload
|
||||||
|
and compare the shortest overload against the maximum value.
|
||||||
|
Other time, it's quite hard determine a long parameter list. By default,
|
||||||
|
a method with 6 or more arguments will be flagged as a defect.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public void MethodWithLongParameterList (int x, char c, object obj, bool j, string f,
|
||||||
|
float z, double u, short s, int v, string[] array)
|
||||||
|
{
|
||||||
|
// Method body ...
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public void MethodWithoutLongParameterList (int x, object obj)
|
||||||
|
{
|
||||||
|
// Method body....
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Smells.AvoidMessageChainsRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for the Message Chain smell. This can cause problems because it
|
||||||
|
means that your code is heavily coupled to the navigation structure.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
public void Method (Person person)
|
||||||
|
{
|
||||||
|
person.GetPhone ().GetAreaCode ().GetCountry ().Language.ToFrench ("Hello world");
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public void Method (Language language)
|
||||||
|
{
|
||||||
|
language.ToFrench ("Hello world");
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Smells.AvoidSpeculativeGeneralityRule">
|
||||||
|
<summary>
|
||||||
|
This rule allows developers to avoid the Speculative Generality smell.
|
||||||
|
Be careful if you are developing a new framework or a new library,
|
||||||
|
because this rule only inspects the assembly, then if you provide an
|
||||||
|
abstract base class for extend by third party people, then the rule
|
||||||
|
can warn you. You can ignore the message in this special case.
|
||||||
|
We detect this smell by looking for:
|
||||||
|
<list type="bullet"><item><description>Abstract classes without responsibility</description></item><item><description>Unnecessary delegation.</description></item><item><description>Unused parameters.</description></item></list></summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
// An abstract class with only one subclass.
|
||||||
|
public abstract class AbstractClass {
|
||||||
|
public abstract void MakeStuff ();
|
||||||
|
}
|
||||||
|
public class OverriderClass : AbstractClass {
|
||||||
|
public override void MakeStuff ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code>
|
||||||
|
If you use Telephone class only in one client, perhaps you don't need this kind of delegation.
|
||||||
|
<code>
|
||||||
|
public class Person {
|
||||||
|
int age;
|
||||||
|
string name;
|
||||||
|
Telephone phone;
|
||||||
|
}
|
||||||
|
public class Telephone {
|
||||||
|
int areaCode;
|
||||||
|
int phone;
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
public abstract class OtherAbstractClass{
|
||||||
|
public abstract void MakeStuff ();
|
||||||
|
}
|
||||||
|
public class OtherOverriderClass : OtherAbstractClass {
|
||||||
|
public override void MakeStuff ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class YetAnotherOverriderClass : OtherAbstractClass {
|
||||||
|
public override void MakeStuff ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.Smells.AvoidSwitchStatementsRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks for the Switch Statements smell. This can
|
||||||
|
lead to code duplication, because the same switch could
|
||||||
|
be repeated in various places in your program. Also, if
|
||||||
|
need to do a little change, you may have to change every switch
|
||||||
|
statement. The preferred way to do this is with virtual methods and polymorphism.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
int balance = 0;
|
||||||
|
foreach (Movie movie in movies) {
|
||||||
|
switch (movie.GetTypeCode ()) {
|
||||||
|
case MovieType.OldMovie: {
|
||||||
|
balance += movie.DaysRented * movie.Price / 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MovieType.ChildMovie: {
|
||||||
|
//its an special bargain !!
|
||||||
|
balance += movie.Price;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MovieType.NewMovie: {
|
||||||
|
balance += (movie.DaysRented + 1) * movie.Price;
|
||||||
|
break:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
abstract class Movie {
|
||||||
|
abstract int GetPrice ();
|
||||||
|
}
|
||||||
|
class OldMovie : Movie {
|
||||||
|
public override int GetPrice ()
|
||||||
|
{
|
||||||
|
return DaysRented * Price / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class ChildMovie : Movie {
|
||||||
|
public override int GetPrice ()
|
||||||
|
{
|
||||||
|
return movie.Price;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class NewMovie : Movie {
|
||||||
|
public override int GetPrice ()
|
||||||
|
{
|
||||||
|
return (DaysRented + 1) * Price;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int balance = 0;
|
||||||
|
foreach (Movie movie in movies) {
|
||||||
|
balance += movie.GetPrice ()
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<remarks>This rule is available since Gendarme 2.4</remarks>
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
|
</doc>
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -0,0 +1,109 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<doc>
|
||||||
|
<assembly>
|
||||||
|
<name>Gendarme.Rules.Ui</name>
|
||||||
|
</assembly>
|
||||||
|
<members>
|
||||||
|
<member name="T:Gendarme.Rules.UI.AddMatchingArrangeMeasureOverrideRule">
|
||||||
|
<summary>
|
||||||
|
An object that inherits from System.Windows.FrameworkElement and provides either
|
||||||
|
an ArrangeOverride or MeasureOverride method should also provide the other.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<code>
|
||||||
|
class BadClass : System.Windows.FrameworkElement {
|
||||||
|
protected override Size MeasureOverride (Size availableSize)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<code>
|
||||||
|
class GoodClass : System.Windows.FrameworkElement {
|
||||||
|
protected override Size MeasureOverride (Size availableSize)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
protected override Size ArrangeOverride (Size finalSize)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.UI.GtkSharpExecutableTargetRule">
|
||||||
|
<summary>
|
||||||
|
An executable assembly, i.e. an .exe, refers to the gtk-sharp assembly but isn't
|
||||||
|
compiled using <c>-target:winexe</c>. A console window will be created and shown
|
||||||
|
under Windows (MS runtime) when the application is executed.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<c>gmcs gtk.cs -pkg:gtk-sharp</c></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<c>gmcs gtk.cs -pkg:gtk-sharp -target:winexe</c></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.UI.SystemWindowsFormsExecutableTargetRule">
|
||||||
|
<summary>
|
||||||
|
An executable assembly, i.e. an .exe, refers to the System.Windows.Forms assembly
|
||||||
|
but isn't compiled using <c>-target:winexe</c>. A console window will be created
|
||||||
|
and shown under Windows (MS runtime) when the application is executed which is
|
||||||
|
probably not desirable for a winforms application.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example:
|
||||||
|
<c>gmcs swf.cs -pkg:dotnet</c></example>
|
||||||
|
<example>
|
||||||
|
Good example:
|
||||||
|
<c>gmcs swf.cs -pkg:dotnet -target:winexe</c></example>
|
||||||
|
</member>
|
||||||
|
<member name="T:Gendarme.Rules.UI.UseSTAThreadAttributeOnSWFEntryPointsRule">
|
||||||
|
<summary>
|
||||||
|
This rule checks executable assemblies, i.e. *.exe's, that reference
|
||||||
|
System.Windows.Forms to
|
||||||
|
ensure that their entry point is decorated with <c>[System.STAThread]</c> attribute
|
||||||
|
and is not decorated with <c>[System.MTAThread]</c> attribute to ensure that Windows
|
||||||
|
Forms work properly.
|
||||||
|
</summary>
|
||||||
|
<example>
|
||||||
|
Bad example #1 (no attributes):
|
||||||
|
<code>
|
||||||
|
public class WindowsFormsEntryPoint {
|
||||||
|
static void Main ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Bad example #2 (MTAThread)
|
||||||
|
<code>
|
||||||
|
public class WindowsFormsEntryPoint {
|
||||||
|
[MTAThread]
|
||||||
|
static void Main ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example #1 (STAThread):
|
||||||
|
<code>
|
||||||
|
public class WindowsFormsEntryPoint {
|
||||||
|
[STAThread]
|
||||||
|
static void Main ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
<example>
|
||||||
|
Good example #2 (not Windows Forms):
|
||||||
|
<code>
|
||||||
|
public class ConsoleAppEntryPoint {
|
||||||
|
static void Main ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></example>
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
|
</doc>
|
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -0,0 +1,135 @@
|
||||||
|
<gendarme>
|
||||||
|
<ruleset name="default">
|
||||||
|
<rules include="*" from="Gendarme.Rules.BadPractice.dll"/>
|
||||||
|
<rules include="*" from="Gendarme.Rules.Concurrency.dll" />
|
||||||
|
<rules include="*" from="Gendarme.Rules.Correctness.dll"/>
|
||||||
|
<rules include="*" from="Gendarme.Rules.Design.dll"/>
|
||||||
|
<rules include="*" from="Gendarme.Rules.Design.Generic.dll"/>
|
||||||
|
<rules include="*" from="Gendarme.Rules.Design.Linq.dll"/>
|
||||||
|
<rules include="*" from="Gendarme.Rules.Exceptions.dll" />
|
||||||
|
<rules include="*" from="Gendarme.Rules.Interoperability.dll"/>
|
||||||
|
<rules include="*" from="Gendarme.Rules.Naming.dll"/>
|
||||||
|
<rules include="*" from="Gendarme.Rules.Performance.dll" />
|
||||||
|
<rules include="*" from="Gendarme.Rules.Portability.dll" />
|
||||||
|
<rules include="*" from="Gendarme.Rules.Security.dll" />
|
||||||
|
<rules include="*" from="Gendarme.Rules.Security.Cas.dll" />
|
||||||
|
<rules include="*" from="Gendarme.Rules.Serialization.dll" />
|
||||||
|
<rules include="*" from="Gendarme.Rules.Ui.dll" />
|
||||||
|
<rules include="*" from="Gendarme.Rules.Maintainability.dll"/>
|
||||||
|
<rules include="*" from="Gendarme.Rules.Globalization.dll"/>
|
||||||
|
<!-- no rule from Gendarme.Rules.Gendarme is included in this set -->
|
||||||
|
<!-- no rule from Gendarme.Rules.Interoperability.Com is included in this set -->
|
||||||
|
<!-- no rule from Gendarme.Rules.NUnit is included in this set -->
|
||||||
|
<!-- no rule from Gendarme.Rules.Smells is included in this set -->
|
||||||
|
</ruleset>
|
||||||
|
|
||||||
|
<ruleset name="xamarin">
|
||||||
|
<rules include="*" from="Gendarme.Rules.Xamarin.dll"/>
|
||||||
|
</ruleset>
|
||||||
|
|
||||||
|
<ruleset name="component-store">
|
||||||
|
<rules include="*" from="Gendarme.Rules.BadPractice.dll"/>
|
||||||
|
<rules include="*" from="Gendarme.Rules.Concurrency.dll" />
|
||||||
|
<rules include="*" from="Gendarme.Rules.Correctness.dll"/>
|
||||||
|
<rules include="*" from="Gendarme.Rules.Design.dll"/>
|
||||||
|
<rules include="*" from="Gendarme.Rules.Design.Generic.dll"/>
|
||||||
|
<rules include="*" from="Gendarme.Rules.Design.Linq.dll"/>
|
||||||
|
<rules include="*" from="Gendarme.Rules.Exceptions.dll" />
|
||||||
|
<rules include="*" from="Gendarme.Rules.Interoperability.dll"/>
|
||||||
|
<rules include="*" from="Gendarme.Rules.Naming.dll"/>
|
||||||
|
<rules include="*" from="Gendarme.Rules.Performance.dll" />
|
||||||
|
<rules include="*" from="Gendarme.Rules.Portability.dll" />
|
||||||
|
<rules include="*" from="Gendarme.Rules.Security.dll" />
|
||||||
|
<rules include="*" from="Gendarme.Rules.Security.Cas.dll" />
|
||||||
|
<rules include="*" from="Gendarme.Rules.Serialization.dll" />
|
||||||
|
<rules include="*" from="Gendarme.Rules.Maintainability.dll"/>
|
||||||
|
<rules include="*" from="Gendarme.Rules.Globalization.dll"/>
|
||||||
|
<rules include="*" from="Gendarme.Rules.Xamarin.dll"/>
|
||||||
|
<!-- no rule from Gendarme.Rules.Gendarme is included in this set -->
|
||||||
|
<!-- no rule from Gendarme.Rules.Interoperability.Com is included in this set -->
|
||||||
|
<!-- no rule from Gendarme.Rules.NUnit is included in this set -->
|
||||||
|
<!-- no rule from Gendarme.Rules.Smells is included in this set -->
|
||||||
|
</ruleset>
|
||||||
|
|
||||||
|
<ruleset name="mono-bcl">
|
||||||
|
<rules include="*" from="Gendarme.Rules.BadPractice.dll"/>
|
||||||
|
<rules include="*" from="Gendarme.Rules.Concurrency.dll"/>
|
||||||
|
<rules include="*" exclude="AvoidConstructorsInStaticTypesRule | MethodCanBeMadeStaticRule | NullDerefRule"
|
||||||
|
from="Gendarme.Rules.Correctness.dll"/>
|
||||||
|
<!-- no rule from Design is included in this set -->
|
||||||
|
<rules include="DontDestroyStackTraceRule" from="Gendarme.Rules.Exceptions.dll"/>
|
||||||
|
<rules include="*" from="Gendarme.Rules.Interoperability.dll"/>
|
||||||
|
<!-- no rule from Naming is included in this set -->
|
||||||
|
<rules include="IDisposableWithDesctuctorWithoutSupressFinalizeRule | DontIgnoreMethodResultRule |
|
||||||
|
UseStringEmptyRule | AvoidToStringOnStringsRule | UsingStringLengthInsteadOfCheckingEmptyStringRule"
|
||||||
|
from="Gendarme.Rules.Performance.dll"/>
|
||||||
|
<rules include="*" exclude="MonoCompatibilityReviewRule" from="Gendarme.Rules.Portability.dll"/>
|
||||||
|
<rules include="*" exclude="ArrayFieldsShouldNotBeReadOnlyRule | NativeFieldsShouldNotBeVisibleRule"
|
||||||
|
from="Gendarme.Rules.Security.dll"/>
|
||||||
|
<!-- no rule from Ui is included in this set -->
|
||||||
|
</ruleset>
|
||||||
|
|
||||||
|
<ruleset name="concurrency">
|
||||||
|
<rules include="*" from="Gendarme.Rules.Concurrency.dll" />
|
||||||
|
</ruleset>
|
||||||
|
<ruleset name="correctness">
|
||||||
|
<rules include="*" from="Gendarme.Rules.Correctness.dll" />
|
||||||
|
</ruleset>
|
||||||
|
<ruleset name="security">
|
||||||
|
<rules include="*" from="Gendarme.Rules.Security.dll" />
|
||||||
|
</ruleset>
|
||||||
|
<ruleset name="security-cas">
|
||||||
|
<rules include="*" from="Gendarme.Rules.Security.Cas.dll" />
|
||||||
|
</ruleset>
|
||||||
|
<ruleset name="performance">
|
||||||
|
<rules include="*" from="Gendarme.Rules.Performance.dll" />
|
||||||
|
</ruleset>
|
||||||
|
<ruleset name="portability">
|
||||||
|
<rules include="*" from="Gendarme.Rules.Portability.dll" />
|
||||||
|
</ruleset>
|
||||||
|
<ruleset name="exceptions">
|
||||||
|
<rules include="*" from="Gendarme.Rules.Exceptions.dll" />
|
||||||
|
</ruleset>
|
||||||
|
<ruleset name="ui">
|
||||||
|
<rules include="*" from="Gendarme.Rules.Ui.dll" />
|
||||||
|
</ruleset>
|
||||||
|
<ruleset name="naming">
|
||||||
|
<rules include="*" from="Gendarme.Rules.Naming.dll"/>
|
||||||
|
</ruleset>
|
||||||
|
<ruleset name="unit-test">
|
||||||
|
<rules include="*" from="Gendarme.Rules.NUnit.dll"/>
|
||||||
|
</ruleset>
|
||||||
|
<ruleset name="smells">
|
||||||
|
<rules include="*" from="Gendarme.Rules.Smells.dll"/>
|
||||||
|
</ruleset>
|
||||||
|
<ruleset name="badpractice">
|
||||||
|
<rules include="*" from="Gendarme.Rules.BadPractice.dll"/>
|
||||||
|
</ruleset>
|
||||||
|
<ruleset name="design">
|
||||||
|
<rules include="*" from="Gendarme.Rules.Design.dll"/>
|
||||||
|
</ruleset>
|
||||||
|
<ruleset name="design-generic">
|
||||||
|
<rules include="*" from="Gendarme.Rules.Design.Generic.dll"/>
|
||||||
|
</ruleset>
|
||||||
|
<ruleset name="design-linq">
|
||||||
|
<rules include="*" from="Gendarme.Rules.Design.Linq.dll"/>
|
||||||
|
</ruleset>
|
||||||
|
<ruleset name="interoperability">
|
||||||
|
<rules include="*" from="Gendarme.Rules.Interoperability.dll"/>
|
||||||
|
</ruleset>
|
||||||
|
<ruleset name="interop-com">
|
||||||
|
<rules include="*" from="Gendarme.Rules.Interoperability.Com.dll"/>
|
||||||
|
</ruleset>
|
||||||
|
<ruleset name="serialization">
|
||||||
|
<rules include="*" from="Gendarme.Rules.Serialization.dll"/>
|
||||||
|
</ruleset>
|
||||||
|
<ruleset name="maintainability">
|
||||||
|
<rules include="*" from="Gendarme.Rules.Maintainability.dll"/>
|
||||||
|
</ruleset>
|
||||||
|
<ruleset name="gendarme">
|
||||||
|
<rules include="*" from="Gendarme.Rules.Gendarme.dll"/>
|
||||||
|
</ruleset>
|
||||||
|
<ruleset name="globalization">
|
||||||
|
<rules include="*" from="Gendarme.Rules.Globalization.dll"/>
|
||||||
|
</ruleset>
|
||||||
|
</gendarme>
|
|
@ -0,0 +1,51 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="3.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProductVersion>10.0.0</ProductVersion>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
<ProjectGuid>{6C4585A1-E675-4ABF-8D99-456EFDB1B8E8}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<RootNamespace>Xamarin.Components.Analysis</RootNamespace>
|
||||||
|
<AssemblyName>Gendarme.Rules.Xamarin</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>..\bin</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<ConsolePause>false</ConsolePause>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>..\bin</OutputPath>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<ConsolePause>false</ConsolePause>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="mscorlib" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="Gendarme.Framework">
|
||||||
|
<HintPath>..\bin\Gendarme.Framework.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Mono.Cecil">
|
||||||
|
<HintPath>..\bin\Mono.Cecil.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="TargetsPrereleaseXamarinIOS.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="..\bin\rules.xml">
|
||||||
|
<Link>rules.xml</Link>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
|
@ -0,0 +1,20 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||||
|
# Visual Studio 2008
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gendarme.Rules.Xamarin", "Gendarme.Rules.Xamarin.csproj", "{6C4585A1-E675-4ABF-8D99-456EFDB1B8E8}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{6C4585A1-E675-4ABF-8D99-456EFDB1B8E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{6C4585A1-E675-4ABF-8D99-456EFDB1B8E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{6C4585A1-E675-4ABF-8D99-456EFDB1B8E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{6C4585A1-E675-4ABF-8D99-456EFDB1B8E8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(MonoDevelopProperties) = preSolution
|
||||||
|
StartupItem = Gendarme.Rules.Xamarin.csproj
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
|
@ -0,0 +1,29 @@
|
||||||
|
<Properties>
|
||||||
|
<MonoDevelop.Ide.Workspace ActiveConfiguration="Debug" />
|
||||||
|
<MonoDevelop.Ide.Workbench ActiveDocument="TargetsPrereleaseXamarinIOS.cs">
|
||||||
|
<Files>
|
||||||
|
<File FileName="TargetsPrereleaseXamarinIOS.cs" Line="1" Column="1" />
|
||||||
|
</Files>
|
||||||
|
<Pads>
|
||||||
|
<Pad Id="ProjectPad">
|
||||||
|
<State expanded="True">
|
||||||
|
<Node name="Gendarme.Rules.Xamarin" expanded="True" selected="True">
|
||||||
|
<Node name="Properties" expanded="True" />
|
||||||
|
</Node>
|
||||||
|
</State>
|
||||||
|
</Pad>
|
||||||
|
<Pad Id="ClassPad">
|
||||||
|
<State expanded="True" selected="True" />
|
||||||
|
</Pad>
|
||||||
|
<Pad Id="MonoDevelop.Debugger.WatchPad">
|
||||||
|
<State>
|
||||||
|
<Value>refs[467]</Value>
|
||||||
|
</State>
|
||||||
|
</Pad>
|
||||||
|
</Pads>
|
||||||
|
</MonoDevelop.Ide.Workbench>
|
||||||
|
<MonoDevelop.Ide.DebuggingService.Breakpoints>
|
||||||
|
<BreakpointStore />
|
||||||
|
</MonoDevelop.Ide.DebuggingService.Breakpoints>
|
||||||
|
<MonoDevelop.Ide.DebuggingService.PinnedWatches />
|
||||||
|
</Properties>
|
|
@ -0,0 +1,27 @@
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
// Information about this assembly is defined by the following attributes.
|
||||||
|
// Change them to the values specific to your project.
|
||||||
|
|
||||||
|
[assembly: AssemblyTitle("Gendarme.Rules.Xamarin")]
|
||||||
|
[assembly: AssemblyDescription("Static analysis rules for Xamarin.iOS.")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("Xamarin")]
|
||||||
|
[assembly: AssemblyProduct("Gendarme.Rules.Xamarin")]
|
||||||
|
[assembly: AssemblyCopyright("Xamarin")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
|
||||||
|
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
|
||||||
|
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
|
||||||
|
|
||||||
|
[assembly: AssemblyVersion("0.1.*")]
|
||||||
|
|
||||||
|
// The following attributes are used to specify the signing key for the assembly,
|
||||||
|
// if desired. See the Mono documentation for more information about signing.
|
||||||
|
|
||||||
|
//[assembly: AssemblyDelaySign(false)]
|
||||||
|
//[assembly: AssemblyKeyFile("")]
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using Mono.Cecil;
|
||||||
|
|
||||||
|
using Gendarme.Framework;
|
||||||
|
|
||||||
|
namespace Gendarme.Rules.Xamarin
|
||||||
|
{
|
||||||
|
[Problem ("A Xamarin.iOS assembly was built with a pre-release version, instead of the latest stable release.")]
|
||||||
|
[Solution ("Rebuild the assemby using Xamarin.iOS 6.2.x.")]
|
||||||
|
public sealed class TargetsPrereleaseXamarinIOS : Rule, IAssemblyRule
|
||||||
|
{
|
||||||
|
public RuleResult CheckAssembly (AssemblyDefinition assembly)
|
||||||
|
{
|
||||||
|
// Look for the TargetPlatform attribute, which indicates
|
||||||
|
// .NET 4.0 support. This is only available in XI 6.3+.
|
||||||
|
// e.g. TargetFramework ("MonoTouch,Version=v4.0", DisplayName = "MonoTouch")
|
||||||
|
var result = assembly.CustomAttributes.Any (attrib =>
|
||||||
|
attrib.AttributeType.Name == "TargetFrameworkAttribute"
|
||||||
|
&& attrib.ConstructorArguments.Any (carg => carg.Value.Equals("MonoTouch,Version=v4.0"))
|
||||||
|
);
|
||||||
|
|
||||||
|
// Now we attempt to detect the use of type/members that were not available in MonoTouch 6.2.x.
|
||||||
|
// There's no point in checking if we already know we have a violation.
|
||||||
|
if (!result && TargetsPrereleaseXamarinIOS.CheckForMT2002 (assembly))
|
||||||
|
result = true;
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
Runner.Report (assembly, Severity.Critical, Confidence.High, "This assembly was not compiled using Xamarin.iOS Stable.");
|
||||||
|
|
||||||
|
return result ? RuleResult.Failure : RuleResult.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks for the conditions that result in MT2002.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// error MT2002: Failed to resolve "System.Boolean System.Type::op_Equality(System.Type,System.Type)" reference from "mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||||
|
/// </remarks>
|
||||||
|
/// <returns><c>true</c>, if the module references the equality operator overload on System.Type, <c>false</c> otherwise.</returns>
|
||||||
|
/// <param name="assembly">Assembly.</param>
|
||||||
|
static bool CheckForMT2002 (AssemblyDefinition assembly)
|
||||||
|
{
|
||||||
|
var result = false;
|
||||||
|
// We need to see if this module's member references table
|
||||||
|
// has an entry to a method that we know was not implemented
|
||||||
|
// in Stable, but was implemented in Beta or Alpha.
|
||||||
|
var refs = assembly.MainModule.GetMemberReferences ();
|
||||||
|
|
||||||
|
var badRef = refs.SingleOrDefault (m => m.FullName == "System.Boolean System.Type::op_Equality(System.Type,System.Type)");
|
||||||
|
if (badRef != null)
|
||||||
|
result = true;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Загрузка…
Ссылка в новой задаче