2013-05-04 7 views
7

В C# я хочу сделать «умные» перечисления, вроде как в Java, где есть дополнительная информация, связанная с значением enum, чем только базовый int. Я наткнулся на схему создания класса (вместо перечисления), как показано в следующем простом примере:C# изменчивость - VS Code Analysis дает мне CA2104? Кажется ... бедным. Я не понимаю?

public sealed class C 
{ 
    public static readonly C C1 = new C(0, 1); 
    public static readonly C C2 = new C(2, 3); 

    private readonly int x; 
    private readonly int y; 

    private C(int x, int y) 
    { 
     this.x = x; 
     this.y = y; 
    } 

    public int X 
    { 
     get 
     { 
      return this.x; 
     } 
    } 

    public int Y 
    { 
     get 
     { 
      return this.y; 
     } 
    } 
} 

Но когда я бегу из Visual Studio «Code Analyzer» на том, что он дает мне предупреждение C2104, " Не объявляйте только изменяемые типы ссылок для чтения ».

Я понимаю, почему вы вообще не хотели бы объявлять только изменяемые ссылочные типы только для чтения, но ... мой класс не изменчив, не так ли?

Чтение документов для предупреждения, похоже, что они просто предполагают, что любой ссылочный тип только для чтения является изменяемым. Например, в нем говорится, что если тип действительно непреложный, то не стесняйтесь подавлять это предупреждение. И на самом деле это дает мне такое же предупреждение для следующего еще более простого класса:

public sealed class C 
{ 
    public static readonly C C1 = new C(); 
    public static readonly C C2 = new C(); 

    private C() 
    { 
    } 
} 

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

(1) Так что, если я полностью не выключу этот чек, я должен подавлять его каждый раз, когда я когда-либо использую неизменяемый член только для чтения, который я мог бы делать сотнями раз для любого данного перечисления?

(2) Но хуже, даже если я это сделаю, тогда кто-то позже может случайно ввести изменчивость, но кто-то еще будет иметь ложное чувство безопасности, данное тем, что кто-то вручную помещает там подавление, говоря: «Я проверил и это непреложно »?

+0

У меня был подобный вопрос: http://stackoverflow.com/questions/15740025/the-ca2104-warning-is-there-any-way-to-mark-a-class-as-immutable- to-suppress –

ответ

5

Вы правы - это ложный позитив в этом сценарии. Ваш единственный выбор - подавить индивидуально или отключить предупреждение, а нижние - точно так же, как вы описали для каждой опции.

Другие варианты, чтобы избежать этого предупреждения включают:

  • Не используйте статические поля. Вместо этого вы можете использовать статическое свойство с общедоступным get и private set и инициализировать конструктор вместо встроенного.

  • Сделайте эти неизменные типы значений, которые будут обходить предупреждение, но потенциально могут привести к поведению в некоторых сценариях. Это может быть или не быть вариантом в вашем случае.

+0

Изменение его на тип значения действительно сработало - спасибо! Я думаю, что должно быть хорошо, как я хочу его использовать, поэтому я начну делать это таким образом и буду решать любые другие проблемы, которые могут возникнуть, когда я их встречу. Еще раз спасибо! – user2350774

+0

@ user2350774 Использование свойств на самом деле является моим предпочтением. Публичные поля имеют много недостатков (вы можете искать здесь по нескольким причинам, почему бы избежать полей в публичном API) –

+0

Не уверен, что я это понимаю - я использовал свойства для X и Y. Или вы предлагаете мне также использовать свойства для статических вещей, которые я хочу рассматривать, по сути, как значения перечисления? – user2350774