Statische Member nicht in generischen Typen deklarieren
Aktualisiert: November 2007
TypeName |
DoNotDeclareStaticMembersOnGenericTypes |
CheckId |
CA1000 |
Kategorie |
Microsoft.Design |
Unterbrechende Änderung |
Breaking |
Ursache
Ein extern sichtbarer generischer Typ enthält einen static-Member (Shared in Visual Basic).
Regelbeschreibung
Wenn ein static-Member eines generischen Typs aufgerufen wird, muss das Typargument für den Typ angegeben werden. Wenn ein generischer Instanzmember, der keine Unterstützung für Rückschlüsse bietet, aufgerufen wird, muss das Typargument für den Member angegeben werden. Die Syntax zum Angeben des Typarguments in diesen beiden Fällen ist unterschiedlich und kann schnell verwechselt werden, wie die folgenden Aufrufe verdeutlichen:
' 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>();
Im Prinzip sollten beide vorherigen Deklarationen vermieden werden, sodass das Typargument nicht angegeben werden muss, wenn der Member aufgerufen wird. Daraus ergibt sich eine Syntax zum Aufrufen von Membern in Generika, die sich nicht von der Syntax für nicht generische Typen unterscheidet. Weitere Informationen finden Sie unter Generische Methoden müssen den Typparameter angeben.
Behandlung von Verstößen
Um einen Verstoß gegen diese Regel zu beheben, entfernen Sie den statischen Member, oder ändern Sie ihn in einen Instanzmember.
Wann sollten Warnungen unterdrückt werden?
Unterdrücken Sie keine Warnung dieser Regel. Durch die Bereitstellung von Generika in einer einfach zu verstehenden und verwendenden Syntax wird die Zeit, die Sie zum Erlernen benötigen, reduziert und die Übernahmerate neuer Bibliotheken erhöht.
Beispiel
Im folgenden Beispiel wird eine Methode gezeigt, die diesen Verstoß verursacht.
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!");
}
}
}
}
Im obigen Beispiel wird der Benutzer durch die Deklaration eines statischen Members für einen generischen Typ dazu gezwungen, das Typargument beim Aufruf anzugeben.
Im folgenden Beispiel wird der obige Verstoß korrigiert, indem der Typparameter T aus der Klasse in die Methode verschoben wird und dadurch beim Aufrufen vom Compiler abgeleitet werden kann.
Verwandte Regeln
Übermäßige Anzahl von Parametern in generischen Typen vermeiden
Auflistungen müssen eine generische Schnittstelle implementieren
Generische Listen nicht verfügbar machen
Generische Typen in Membersignaturen nicht schachteln
Generische Methoden müssen den Typparameter angeben
Generische Ereignishandlerinstanzen verwenden
Nach Möglichkeit Generika verwenden