匿名メソッドとコード分析
更新 : 2007 年 11 月
匿名メソッドは、名前を持たないメソッドです。匿名メソッドは、コード ブロックをデリゲート パラメータとして渡すために最も頻繁に使用されます。
このトピックでは、匿名メソッドに関連付けられた警告やメトリックスがコード分析でどのように処理されるかについて説明します。
メンバ内で宣言された匿名メソッド
メソッドやアクセサなど、メンバで宣言されている匿名メソッドの警告やメトリックスは、メソッドを宣言するメンバに関連付けられます。メソッドを呼び出すメンバには関連付けられません。
使用例
[Description]
たとえば、次のクラスでは、anonymousMethod の宣言内にあるすべての警告は、Method2 ではなく Method1 に対して発生させる必要があります。
[コード]
Imports System
Delegate Function ADelegate(ByVal value As Integer) As Boolean
Class AClass
Sub Method1()
Dim anonymousMethod As ADelegate = Function(ByVal value As Integer) value > 5
Method2(anonymousMethod)
End Sub
Sub Method2(ByVal anonymousMethod As ADelegate)
anonymousMethod(10)
End Sub
End Class
using System;
delegate void Delegate();
class Class1
{
void Method1()
{
Delegate anonymousMethod = delegate()
{
Console.WriteLine("");
};
Method2(anonymousMethod);
}
void Method2(Delegate anonymousMethod)
{
anonymousMethod();
}
}
インラインの匿名メソッド
フィールドへのインラインの代入として宣言された匿名メソッドの警告やメトリックスは、コンストラクタに関連付けられます。フィールドが static (Visual Basic 内の Shared) として宣言されている場合、警告とメトリックスはクラス コンストラクタに関連付けらます。それ以外の場合は、インスタンス コンストラクタに関連付けられます。
使用例
[Description]
たとえば、次のクラスでは、anonymousMethod1 の宣言内にあるすべての警告は、暗黙的に生成された Class の既定のコンストラクタに対して発生します。一方、anonymousMethod2 内にある警告は、暗黙的に生成されたクラス コンストラクタに対して適用されます。
[コード]
Imports System
Delegate Function ADelegate(ByVal value As Integer) As Boolean
Class AClass
Dim anonymousMethod1 As ADelegate = Function(ByVal value As Integer) value > 5
Shared anonymousMethod2 As ADelegate = Function(ByVal value As Integer) value > 5
Sub Method1()
anonymousMethod1(10)
anonymousMethod2(10)
End Sub
End Class
using System;
namespace Sample
{
delegate void Delegate();
class Class2
{
Delegate anonymousMethod1 = delegate()
{
Console.WriteLine("");
};
static Delegate anonymousMethod2 = delegate()
{
Console.WriteLine("");
};
void Method()
{
anonymousMethod1();
anonymousMethod2();
}
}
}
クラスには、複数のコンストラクタを持つフィールドに値を割り当てる、インラインの匿名メソッドが含まれることがあります。この場合、そのコンストラクタが同じクラスの別のコンストラクタにチェーンしている限り、警告とメトリックスはすべてのコンストラクタに関連付けられます。
使用例
[Description]
たとえば、次のクラスでは、anonymousMethod の宣言内にあるすべての警告は、Class(int) および Class(string) に対して発生させる必要がありますが、Class() に対して発生させる必要はありません。
[コード]
Imports System
Delegate Function ADelegate(ByVal value As Integer) As Boolean
Class AClass
Dim anonymousMethod As ADelegate = Function(ByVal value As Integer) value > 5
Sub New()
End Sub
Sub New(ByVal a As Integer)
End Sub
Sub New(ByVal a As String)
End Sub
End Class
using System;
delegate void Delegate();
class Class
{
Delegate anonymousMethod = delegate()
{
Console.WriteLine("");
};
Class()
: this((string)null)
{
}
Class(int a)
{
}
Class(string a)
{
}
}
予想外に思えるかもしれませんが、これは、コンパイラが別のコンストラクタにチェーンしていないすべてのコンストラクタに一意のメソッドを出力するために発生します。この動作のため、anonymousMethod 内で発生するすべての違反は個別に抑制する必要があります。また、新しいコンストラクタが導入された場合は、それまで Class(int) と Class(string) に対して抑制していた警告を、新しいコンストラクタに対しても抑制する必要があります。
この問題は、2 つの方法のいずれかで回避することができます。すべてのコンストラクタにチェーンしている共通のコンストラクタ内に anonymousMethod を宣言します。または、すべてのコンストラクタから呼び出される初期化メソッド内に宣言します。