2016-08-30 2 views
1

У меня есть информация, которая не изменяется во время выполнения программы. Это своего рода статическая информация. Я использую следующий код:Как объявить постоянную ссылку только для чтения?

public class Foo 
{ 
    public static readonly List<int> = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 
}; 

К сожалению, во время выполнения программы, я могу изменить поля такого static элемента. В результате у меня появляется следующее предупреждение:

«Не объявлять только изменяемые типы ссылок для чтения».

Что лучше всего справляться с этой проблемой?

+0

является 'TypeFace' ваш собственный класс? Если да, можете ли вы сделать его неизменным или «необязательно неизменным» (например, «CultureInfo')? В общем, я предлагаю выставлять свойства, а не поля, btw ... и следующие соглашения об именах .NET. –

+0

@ Jon Skeet, это системный класс. Как я могу сделать его неизменным? – LmTinyToon

+1

На первый взгляд, это выглядит неизменным уже. Какие свойства вы можете изменить? –

ответ

3

В C# невозможно сделать членов чужого класса неизменными. Я предполагаю, что вы знакомы с концепцией C++ ссылки на const, но у C# ничего подобного нет.

Если вы хотите контролировать доступ, я бы сделал шрифт частным и добавил статические свойства и методы только для чтения в Foo. Это означает, что вы можете получить доступ только для чтения;

Foo.TypeFaceSize; 
Foo.TypeFaceName; 
+0

Как я понял, единственный способ использовать кодовые контракты для проверки возможных изменений этого поля? – LmTinyToon

+1

Я не пробовал - мне было бы интересно узнать, преуспеете ли вы. Мне кажется, что TypeFace на самом деле неизменен, но компилятор этого не знает - я бы предпочел подавить предупреждение в коде - https://msdn.microsoft.com/en-us/library/ms244717.aspx –

1

Компилятор C# может обеспечивать только доступ к readonly для свойства или поля. Если вы делаете поле только для чтения, настраиваемые свойства объекта в этом поле все еще устанавливаются, и единственный способ изменить это - изменить определение класса объекта.

Возможно, вы можете обернуть объект в свой собственный пользовательский класс и разрешить только геттеры. Но вам может потребоваться несколько слоев оберток, поэтому я бы предложил не делать этого и просто обращать внимание на предупреждения компилятора.

1

Вы не можете превратить изменяемый тип в неизменяемый тип в C# как есть.

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

public class A 
{ 
    public string Text { get; set; } 
} 

public class AReadOnly 
{ 
    public AReadOnly(A a) 
    { 
     A = a; 
    } 

    private A A { get; } 

    public string Text => A.Text; 
} 

public class B 
{ 
    public B() 
    { 
     A = new AReadOnly(_A); 
    } 

    private A _A { get; } = new A(); 
    public AReadOnly A { get; } 
} 
Смежные вопросы