Не объявляйте статические элементы в универсальных типах
Обновлен: Ноябрь 2007
TypeName |
DoNotDeclareStaticMembersOnGenericTypes |
CheckId |
CA1000 |
Категория |
Microsoft.Design |
Критическое изменение |
Критическое |
Причина
Видимый снаружи универсальный тип содержит элемент с модификатором static (Shared в Visual Basic).
Описание правила
При вызове метода универсального типа с модификатором static для типа нужно указать аргумент типа. При вызове универсального экземпляра элемента, не поддерживающего вывод типа, для элемента нужно указать аргумент типа. Синтаксис для аргумента типа различается в этих двух случаях, его легко перепутать, как показано в следующих вызовах:
' 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) из класса в метод, что позволяет компилятору определять его при вызове.
Связанные правила
Не используйте слишком много параметров в универсальных типах
Коллекции должны реализовать универсальный интерфейс
Не следует раскрывать универсальные списки
Не вкладывайте универсальные типы в подписи членов
Универсальные методы должны предоставлять параметр типа
Используйте экземпляры обработчика универсальных событий
Используйте универсальные методы, если это уместно
См. также
Ссылки
Универсальные шаблоны (Руководство по программированию на C#)