Это поведение не определено.В языке программирования C # в конце раздела спецификаций C # 4.0 7.6.4 (доступ к элементам) Питер Сестофт заявляет:
Две маркированные точки, указывающие «если полетолько для чтения ... тогда результатом является значение "немного удивительно, когда поле имеет тип структуры, а этот тип структуры имеет изменяемое поле (не рекомендуемая комбинация - см. другие примечания по этому вопросу).
Он приводит пример.Я создал свой собственный пример, который отображает более подробно ниже.
Затем он продолжает:
Несколько странно, если бы вместо s была локальная переменная типа структуры, объявленная в операторе using, что также приводит к созданию sнеизменным, затем s.SetX () обновляет sx, как и ожидалось.
Здесь мы видим, что один из авторов признает, что это поведение противоречиво.Согласно разделу 7.6.4, поля только для чтения обрабатываются как значения и не изменяются (копии изменяются).Поскольку в разделе 8.13 говорится, что использование операторов рассматривает ресурсы только для чтения:
переменная ресурса доступна только для чтения во встроенном операторе,
ресурсы в операторах using
должен вести себя как поля только для чтения.По правилам 7.6.4 мы должны иметь дело со значением , а не переменной.Но удивительно, что первоначальная стоимость ресурса действительно меняется , как показано в этом примере:
//Sections relate to C# 4.0 spec
class Test
{
readonly S readonlyS = new S();
static void Main()
{
Test test = new Test();
test.readonlyS.SetX();//valid we are incrementing the value of a copy of readonlyS. This is per the rules defined in 7.6.4
Console.WriteLine(test.readonlyS.x);//outputs 0 because readonlyS is a value not a variable
//test.readonlyS.x = 0;//invalid
using (S s = new S())
{
s.SetX();//valid, changes the original value.
Console.WriteLine(s.x);//Surprisingly...outputs 2. Although S is supposed to be a readonly field...the behavior diverges.
//s.x = 0;//invalid
}
}
}
struct S : IDisposable
{
public int x;
public void SetX()
{
x = 2;
}
public void Dispose()
{
}
}
Ситуация странная.Итог, избегайте создания изменяемых только для чтения полей.