No declare miembros estáticos en tipos genéricos
Actualización: noviembre 2007
TypeName |
DoNotDeclareStaticMembersOnGenericTypes |
Identificador de comprobación |
CA1000 |
Category |
Microsoft.Design |
Cambio problemático |
Sí |
Motivo
Un tipo genérico visible externamente contiene un miembro static (Shared en Visual Basic).
Descripción de la regla
Cuando se llama a un miembro static de un tipo genérico, se debe especificar el argumento de tipo correspondiente a ese tipo. Cuando se llama a un miembro de instancia genérico que no admite la interferencia, se debe especificar el argumento de tipo para el miembro. La sintaxis para especificar el argumento de tipo en estos dos casos es diferente y resulta fácil confundirse, como se muestra en las llamadas siguientes:
' 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>();
En general, las dos declaraciones anteriores deben evitarse, para que no sea necesario llamar al argumento de tipo cuando se llame al miembro. Esto produce una sintaxis para llamar a los miembros de los tipos genéricos que no se diferencia de la sintaxis de los tipos no genéricos. Para obtener más información, vea Los métodos genéricos deben proporcionar el parámetro de tipo.
Cómo corregir infracciones
Para corregir una infracción de esta regla, quite el miembro estático o cámbielo por un miembro de instancia.
Cuándo suprimir advertencias
No suprima las advertencias de esta regla. Al proporcionar genéricos con una sintaxis fácil de entender y utilizar se reduce el tiempo necesario de aprendizaje y se aumenta la velocidad de adopción de nuevas bibliotecas.
Ejemplo
En el ejemplo siguiente se muestra un método que provoca esta infracción.
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!");
}
}
}
}
En el ejemplo anterior, al declarar un miembro estático para un tipo genérico se fuerza al usuario a especificar el argumento de tipo al llamarlo.
En el ejemplo siguiente se corrige la infracción anterior moviendo el parámetro de tipo, T, de la clase al método, con lo que se permite que el compilador lo deduzca al llamarlo.
Reglas relacionadas
Evite el exceso de parámetros en los tipos genéricos
Las colecciones deben implementar la interfaz genérica
No anide los tipos genéricos en firmas de miembro
Los métodos genéricos deben proporcionar el parámetro de tipo
Utilice instancias de control de eventos genéricas
Utilice genéricos cuando resulte apropiado