Подтвердить что ты не робот

Предупреждение CA2104: есть ли способ пометить класс как "неизменяемый" для его подавления?

Рассмотрим следующий код, который вызывает CA2104: Do not declare read only mutable reference types.

public class Test
{
    // This provokes CA2104: "Do not declare read only mutable reference types".
    protected readonly ImmutableClass ImmutableMember;
}

public class ImmutableClass
{
}

Кто-нибудь знает способ маркировки класса как непреложный таким образом, чтобы подавить предупреждение CA2104?

Я попытался украсить MutableClass [ImmutableObject(true)] без надежды на успех (так как этот атрибут довольно ясно для редактора форм использование), и, конечно же, это не сработает.

Я предполагаю, что Code Analysis использует список известных неизменяемых типов при определении того, следует ли испускать CA2104, поэтому мы не можем использовать тот же подход.

Я предполагаю, что даже если бы вы могли пометить класс как неизменяемый, не было бы способа, чтобы компилятор действительно проверял, действительно ли это правда, но по крайней мере это может быть полезным индикатором.

В любом случае, есть ли какие-либо атрибуты, которые я пропускаю? Если нет, подавление должно быть выполнено.

Кажется, что альтернативного способа сделать это на данный момент нет.

Я нашел интересный блог от Джо Даффи (автор "Параллельного программирования в Windows" ) об этом виде.

Он начинает с "Представьте, что у нас был ImmutableAttribute."...:)

Это довольно интересно - он столкнулся с проблемой написания каких-то новых правил FxCop, чтобы сделать некоторый анализ типов, приписываемых как неизменные.

4b9b3361

Ответ 1

Поле

A protected readonly на самом деле не так ясно. В качестве protected вы можете ожидать, что производный класс может инициализировать поле:

public class Test
{
    protected readonly ImmutableClass ImmutableMember;
}

public class SpecialTest : Test
{
    public SpecialTest() { ImmutableMember = new ImmutableClass; }
}

Но это не так - вы получите ошибку компиляции (CS0191).

Я не знаю точного толчка за CA2104, но вы можете получить тот же результат без readonly через:

public class Test
{
    protected ImmutableClass ImmutableMember {get; private set;}

    public Test()
        :this(new ImmutableClasse())
    {
    }

    public Test(ImmutableClass immutableClass)
    {
        ImmutableMember = new ImmutableClasse();
    }
}

и избегайте CA2104.

Update:

w.r.t. к комментариям (и будущим читателям), как вы говорите, вы можете использовать поле поддержки, чтобы получить доступ только для чтения и предоставить защищенному получателю доступ к нему в производных классах:

public class Test
{
    private readonly ImmutableClass immutableMember;

    protected ImmutableClass ImmutableMember { get { return immutableMember; } }

    public Test(ImmutableClass immutableMember)
    {
        this.immutableMember = immutableMember;
    }
}