Поделиться через


Не объявляйте статические элементы в универсальных типах

Обновлен: Ноябрь 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#)