不要在泛型型別上宣告靜態成員
更新:2007 年 11 月
TypeName |
DoNotDeclareStaticMembersOnGenericTypes |
CheckId |
CA1000 |
Category |
Microsoft.Design |
Breaking Change |
Breaking |
原因
外部可見的泛型型別包含 static (在 Visual Basic 中為 Shared) 成員。
規則描述
呼叫泛型型別的 static 成員時,必須為型別指定型別引數。呼叫不支援介面的泛型執行個體 (Instance) 成員時,必須為成員指定型別引數。在上述兩種情況下指定型別引數的語法不同且容易混淆,如下列呼叫所示範:
' Shared method in a generic type.
GenericType(Of Integer).SharedMethod()
' Generic instance method that does not support inference.
someObject.GenericMethod(Of Integer)()
// Static method in a generic type.
GenericType<int>.StaticMethod();
// Generic instance method that does not support inference.
someObject.GenericMethod<int>();
一般而言,這兩者都應該避免先宣告,如此在呼叫成員時才不必指定型別引數。呼叫泛型成員的語法結果會與呼叫非泛型的語法結果相同。如需詳細資訊,請參閱泛型方法應該提供型別參數。
如何修正違規
若要修正此規則的違規情形,請移除靜態成員,或將它變更為執行個體成員。
隱藏警告的時機
請勿隱藏此規則的警告。使用易於了解和使用的語法提供泛型,以便減少學習所需的時間,並增加新程式庫的採用率。
範例
以下範例將顯示造成違規的方法。
Imports System
Imports System.Runtime.InteropServices
Namespace Samples
Public NotInheritable Class EnumParser(Of T)
Private Sub New()
End Sub
' Fires this violation
Public Shared Function TryParse(ByVal value As String, <Out()> ByRef result As T) As Boolean
Try
result = DirectCast([Enum].Parse(GetType(T), value), T)
Return True
Catch ex As ArgumentException
End Try
result = Nothing
Return False
End Function
End Class
Module Program
Public Sub Main()
Dim result As DayOfWeek
' Must specify type argument
If EnumParser(Of DayOfWeek).TryParse("Monday", result) Then
Console.WriteLine("Conversion Succeeded!")
End If
End Sub
End Module
End Namespace
using System;
namespace Samples
{
public static class EnumParser<T>
{ // Fires this violation
public static bool TryParse(string value, out T result)
{
try
{
result = (T)Enum.Parse(typeof(T), value);
return true;
}
catch (ArgumentException)
{
}
result = default(T);
return false;
}
}
static class Program
{
public static void Main()
{
DayOfWeek dayOfWeek;
// Must specify type argument
if (EnumParser<DayOfWeek>.TryParse("Monday", out dayOfWeek))
{
Console.WriteLine("Conversion Succeeded!");
}
}
}
}
上面的範例中,在泛型型別上宣告靜態成員會強制使用者在呼叫時指定型別引數。
以下範例會修正上述違規,藉由將型別參數 T 從類別移到方法,以允許在呼叫時由編譯執行推斷。