1

В моем проекте VS2008 SP1, .NET 3.5 SP1 у меня есть разные классы, которые содержат разные свойства. Я много использую свойства C# 3.0.Предупреждение FxCop CA2227 и ReadOnlyCollection <T>

Некоторые из этих свойств должны быть коллекциями. Поскольку я хочу сделать это простым, я использую ReadOnlyCollection<T> для этих свойств.

Я не хочу использовать IEnumerable<T>, так как я хочу случайный доступ к элементам.

Я использую Code Analysis (правила FxCop), и я получаю предупреждение CA2227.

Я не понимаю, почему ReadOnlyCollection<T> должен иметь метод набора, в то время как он не может быть изменен ... Метод set может делать только то, что может сделать свойство.

Пример:

using System.Collections.ObjectModel; 

namespace CA2227 
{ 
    public class MyClass 
    { 
     public ReadOnlyCollection<int> SomeNumbers { get; set; } 
    } 
} 

CA2227: Microsoft.Usage: Изменить 'MyClass.SomeNumbers', чтобы быть только для чтения путем удаления свойства сеттер. C: \ Users ... \ Visual Studio 2008 \ Projects \ CA2227 \ MyClass.cs 7 CA2227

ответ

2

ReadOnlyCollection не может быть изменен, но нет никаких причин, почему это свойство с установщиком, который типа ReadOnlyCollection не может быть изменен для обозначения другого ReadOnlyCollection. Если вы хотите, чтобы свойство SomeNumbers было неизменным, оно должно быть как типа «только для чтения», так и иметь негосударственный сеттер.

EDIT

Если вы уверены в том, что вы хотите, то хотя FxCop является правильным, чтобы предупредить вас, что вы счастливы с предупреждением. Если вы хотите избавиться от него, включите в этот момент атрибут SuppressMessage - если вы еще определите константу CODE_ANALYSIS в свойствах проекта до того, как будете строить, FxCop будет соблюдать этот атрибут и просто не выдаст это конкретное предупреждение для этого конкретного повод.

+1

Я хочу, чтобы иметь возможность изменить значение свойства. Я не хочу получать предупреждение CA2227. Я также хочу понять, почему я получаю предупреждение CA2227 и должен ли я писать код по-другому. – brickner

+0

Ну, в конце концов, это предупреждение о том, что то, что вы делаете, необычно и может быть неправильным. Если вы уверены, что правы - см. Мое редактирование ... –

+1

Я не уверен. Я хочу понять, почему я получаю это предупреждение для ReadOnlyCollection , а не для IEnumerable . – brickner

1

Довольно странно блокировать изменения в содержимом коллекции, не блокируя также изменения самой коллекции. Если вы хотите установить коллекцию из своего класса при сохранении использования автоматических свойств, вы можете использовать частный сеттер. например:

public ReadOnlyCollection<int> SomeNumbers { get; private set; } 
+0

Почему это так странно? Почему установка IEnumerable (которая также не может быть изменена) нечетна и не дает CA2227? Я хочу, чтобы сеттер был публичным. Мне нравится использовать инициализаторы объектов, которые не работают с частными сеттерами. – brickner

+0

Также необычно допускать установку свойства IEnumerable , но, по крайней мере, намерение достаточно ясно, когда это делается, и разработчик класса должен, по-видимому, знать о последствиях. Я полагаю, что можно было бы утверждать то же самое относительно ReadOnlyCollection <>, но правило FxCop, как оно написано в настоящее время, не проверяет, какие объекты ICollection или ICollection <> вы раскрываете. [продолжение в следующем комментарии] –

+0

Я подозреваю, что ваш код, вероятно, небезопасен для действительно «публичного» использования. Если вы не захотите инвестировать в проверку того, что включение вызова setter в любое время не вызовет неожиданных побочных эффектов, вы можете уменьшить видимость сеттера до внутреннего, что в большинстве случаев должно избавиться от нарушения FxCop. –

0

Рассмотрите возможность использования

public class MyClass 
{ 
    public IReadOnlyList<int> SomeNumbers { get; set; } 
} 

ReadOnlyCollection = http://msdn.microsoft.com/en-us/library/ms132474(v=vs.110).aspx

IReadOnlyList = http://msdn.microsoft.com/en-us/library/hh192385(v=vs.110).aspx

Проблема с ReadOnlyCollection, является то, что она по-прежнему наследует от ICollection, и до сих пор .Add , хотя документация говорит, что он будет бросать - http://msdn.microsoft.com/en-us/library/cc672239(v=vs.110).aspx

Смежные вопросы