2013-04-16 3 views
1

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

public class IAmImmutable 
{ 
    public IAmImmutable(string member1, string member2) 
    { 
     this.Member1 = member1; 
     this.Member2 = member2; 
    } 

    public string Member1 { get; private set; } 

    public string Member2 { get; private set; } 

    public static readonly Instance1 = new IAmImmutable("abc", "def"); 
    public static readonly Instance2 = new IAmImmutable("example", "data"); 
    public static readonly Instance3 = new IAmImmutable("for", "stackoverflow"); 
    public static readonly Instance4 = new IAmImmutable("these are", "constant fields"); 
    public static readonly Instance5 = new IAmImmutable("42", "1729"); 
    /* ... */ 
    public static readonly Instance1000 = new IAmImmutable("HUNGRY EVIL", "ZOMBIES"); 
} 

Это приводит к тысячам CA2104:DoNotDeclareReadOnlyMutableReferenceTypes обнаружений от FxCop. Примечания в этом обнаружении указывают на то, что следует подавлять обнаружение, если указанный тип является неизменным, что в этом случае. Тем не менее, я не хочу иметь тысячи и тысячи подавлений, если я могу избежать этого.

Можно ли пометить этот тип неизменным и, следовательно, предотвратить это обнаружение?

+0

http://blogs.msdn.com/b/codeanalysis/archive/2006/04/04/faq-how-do-indicate-to-donotdeclarereadonlymutablereferencetypes-that-a-type-is-immutable-david -kean.aspx –

+0

см. http://stackoverflow.com/questions/2274412/immutable-readonly-reference-types-fxcop-violation-do-not-declare-read-only-m –

+0

@Peter: этот вопрос касается неизменяемый тип, который содержит внутренние изменяемые члены. У этого типа нет внутренних изменчивых членов. Если бы внутри был «StringBuilder», это был бы совсем другой вопрос. –

ответ

2

См. Статью, объясняющую, как это сделать на MSDN.

Похоже, что FxCop ищет текстовый файл с именем ImmutableTypes.txt для типов, которые он должен считать «неизменяемыми».

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

public IAmImmutable(string member1, string member2) 
{ 
    this._Member1 = member1; 
    this._Member2 = member2; 
} 

private readonly string _Member1; 
private readonly string _Member2; 

public string Member1 { get {return _Member1;} } 
public string Member2 { get {return _Member2;} } 

(признает ли это FxCop как «неизменный» класс это другой вопрос)

Обратите внимание, что это только работает, потому что string является неизменным. Если бы он был изменен на изменяемый тип (например, или Array), то ссылка была бы только для чтения, но содержимое могло быть изменено, что делает сам класс изменчивым.

+0

Хм ... У меня нет файла проекта FxCop. (???) –

+0

@ D Стэнли: Не совсем. Добавление readonly только обеспечивает что-либо во время компиляции для этого класса; если бы кто-то добавлял в класс мутирующий элемент, в будущем они могли бы просто добавить этого участника и удалить 'readonly'. Это не было бы изменением. Конечно, это может тонко сломать код, ожидающий «бесплатной потоковой передачи», но структура не будет жаловаться. –

+0

Тот факт, что поле имеет изменяемый ссылочный тип, не означает, что класс изменен, если нет пути выполнения, посредством которого информация, инкапсулированная полем, может фактически измениться. В качестве простого примера, если конструктор объекта создает массив из пяти целых чисел, заполняет эти значения, а затем сохраняет ссылку в закрытом поле, и если он никогда не предоставляет этот массив никому, что может его изменить, я бы рассмотрел класс должен быть неизменным (по крайней мере, в отношении массива). Кроме того, зная, что * идентичность * вещи, на которую указывает поле, является ... – supercat

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