CA1010: Koleksiyonlar genel arabirim uygulamalıdır

Özellik Değer
Kural Kimliği CA1010
Başlık Koleksiyonlar genel arabirimi uygulamalıdır
Kategori Tasarım
Hataya neden olan veya bozulmayan düzeltme Hataya neden olmayan
.NET 8'de varsayılan olarak etkin Hayır

Neden

Bir tür arabirimi uygular System.Collections.IEnumerable , ancak arabirimi uygulamaz System.Collections.Generic.IEnumerable<T> ve içeren derleme .NET'i hedefler. Bu kural uygulayan System.Collections.IDictionarytürleri yoksayar.

Varsayılan olarak, bu kural yalnızca dışarıdan görünen türlere bakar, ancak bu yapılandırılabilir. Ayrıca, genel bir arabirimin uygulanmasını gerektirecek ek arabirimler de yapılandırabilirsiniz.

Kural açıklaması

Bir koleksiyon kullanılabilirliğini genişletmek için genel koleksiyon arabirimlerinden birini uygulayın. Ardından koleksiyon, aşağıdaki gibi genel koleksiyon türlerini doldurmak için kullanılabilir:

İhlalleri düzeltme

Bu kuralın ihlalini düzeltmek için aşağıdaki genel koleksiyon arabirimlerinden birini uygulayın:

Uyarıların ne zaman bastırılması gerekiyor?

Bu kuraldan gelen bir uyarıyı engellemek güvenlidir; ancak koleksiyonun kullanımı daha sınırlı olacaktır.

Uyarıyı gizleme

Yalnızca tek bir ihlali engellemek istiyorsanız, kuralı devre dışı bırakmak ve sonra yeniden etkinleştirmek için kaynak dosyanıza ön işlemci yönergeleri ekleyin.

#pragma warning disable CA1010
// The code that's violating the rule is on this line.
#pragma warning restore CA1010

Bir dosya, klasör veya projenin kuralını devre dışı bırakmak için, yapılandırma dosyasındaki önem derecesini noneolarak ayarlayın.

[*.{cs,vb}]
dotnet_diagnostic.CA1010.severity = none

Daha fazla bilgi için bkz . Kod analizi uyarılarını gizleme.

Çözümlemek için kod yapılandırma

Bu kuralın kod tabanınızın hangi bölümlerinde çalıştırılacaklarını yapılandırmak için aşağıdaki seçenekleri kullanın.

Bu seçenekleri yalnızca bu kural, geçerli olduğu tüm kurallar veya bu kategorideki (Tasarım) tüm kurallar için yapılandırabilirsiniz. Daha fazla bilgi için bkz . Kod kalitesi kuralı yapılandırma seçenekleri.

Belirli API yüzeylerini ekleme

Bu kuralın üzerinde çalıştırılacak kod tabanınızın hangi bölümlerini erişilebilirliklerine göre yapılandırabilirsiniz. Örneğin, kuralın yalnızca genel olmayan API yüzeyinde çalıştırılması gerektiğini belirtmek için projenizdeki bir .editorconfig dosyasına aşağıdaki anahtar-değer çiftini ekleyin:

dotnet_code_quality.CAXXXX.api_surface = private, internal

Ek gerekli genel arabirimler

Arabirim adlarının listesini (ile ayrılmış |) gerekli genel tam arabirimleriyle (ile ayrılmış ->olarak) yapılandırabilirsiniz.

İzin verilen arabirim biçimleri:

  • Yalnızca arabirim adı (içeren tür veya ad alanına bakılmaksızın adı olan tüm arabirimleri içerir).
  • simgenin belge kimliği biçiminde isteğe bağlı T: ön ek içeren tam adlar.

Örnekler:

Seçenek değeri Özet
dotnet_code_quality.CA1010.additional_required_generic_interfaces = ISomething->System.Collections.Generic.IEnumerable`1 Ad alanına bakılmaksızın uygulayan ISomething tüm türlerin de uygulaması System.Collections.Generic.IEnumerable<T>beklenir.
dotnet_code_quality.CA1010.additional_required_generic_interfaces = T:System.Collections.IDictionary->T:System.Collections.Generic.IDictionary`2 Uygulayan System.Collections.IDictionary tüm türlerin de uygulaması System.Collections.Generic.IDictionary<TKey,TValue>beklenir.

Örnek

Aşağıdaki örnek, genel CollectionBase olmayan sınıftan türetilen ve bu kuralı ihlal eden bir sınıfı gösterir.

public class Book
{
    public Book()
    {
    }
}

public class BookCollection : CollectionBase
{
    public BookCollection()
    {
    }

    public void Add(Book value)
    {
        InnerList.Add(value);
    }

    public void Remove(Book value)
    {
        InnerList.Remove(value);
    }

    public void Insert(int index, Book value)
    {
        InnerList.Insert(index, value);
    }

    public Book? this[int index]
    {
        get { return (Book?)InnerList[index]; }
        set { InnerList[index] = value; }
    }

    public bool Contains(Book value)
    {
        return InnerList.Contains(value);
    }

    public int IndexOf(Book value)
    {
        return InnerList.IndexOf(value);
    }

    public void CopyTo(Book[] array, int arrayIndex)
    {
        InnerList.CopyTo(array, arrayIndex);
    }
}

Bu kuralın ihlalini düzeltmek için aşağıdakilerden birini yapın:

Arabirim uygulamasına göre düzeltme

Aşağıdaki örnek, şu genel arabirimleri uygulayarak ihlali düzeltir: IEnumerable<T>, ICollection<T>ve IList<T>.

public class Book
{
    public Book()
    {
    }
}

public class BookCollection : CollectionBase, IList<Book?>
{
    public BookCollection()
    {
    }

    int IList<Book?>.IndexOf(Book? item)
    {
        return this.List.IndexOf(item);
    }

    void IList<Book?>.Insert(int location, Book? item)
    {
    }

    Book? IList<Book?>.this[int index]
    {
        get => (Book?)this.List[index];
        set { }
    }

    void ICollection<Book?>.Add(Book? item)
    {
    }

    bool ICollection<Book?>.Contains(Book? item)
    {
        return true;
    }

    void ICollection<Book?>.CopyTo(Book?[] array, int arrayIndex)
    {
    }

    bool ICollection<Book?>.IsReadOnly
    {
        get { return false; }
    }

    bool ICollection<Book?>.Remove(Book? item)
    {
        if (InnerList.Contains(item))
        {
            InnerList.Remove(item);
            return true;
        }
        return false;
    }

    IEnumerator<Book> IEnumerable<Book?>.GetEnumerator()
    {
        return new BookCollectionEnumerator(InnerList.GetEnumerator());
    }

    private class BookCollectionEnumerator : IEnumerator<Book>
    {
        private IEnumerator _Enumerator;

        public BookCollectionEnumerator(IEnumerator enumerator)
        {
            _Enumerator = enumerator;
        }

        public Book Current
        {
            get { return (Book)_Enumerator.Current; }
        }

        object IEnumerator.Current
        {
            get { return _Enumerator.Current; }
        }

        public bool MoveNext()
        {
            return _Enumerator.MoveNext();
        }

        public void Reset()
        {
            _Enumerator.Reset();
        }

        public void Dispose()
        {
        }
    }
}

Temel sınıf değişikliğine göre düzeltme

Aşağıdaki örnek, koleksiyonun temel sınıfını genel olmayan sınıftan genel CollectionBaseCollection<T> (Collection(Of T) Visual Basic'te) sınıfına değiştirerek ihlali düzeltir.

public class Book
{
    public Book()
    {
    }
}

public class BookCollection : Collection<Book>
{
    public BookCollection()
    {
    }
}

Zaten yayımlanan bir sınıfın temel sınıfını değiştirmek, mevcut tüketiciler için hataya neden olan bir değişiklik olarak kabul edilir.

Ayrıca bkz.