Это невозможно в C #, как это невозможно в C ++.В C ++, если объект действительно является константным, вы не можете const_cast
удалить константу и записать в нее, не вызывая неопределенного поведения:
struct foo { const int x; };
foo a;
int& b = const_cast<int&>(a.x);
b = 17; // invokes undefined behaviour
Поле readonly
в C # означает только то, что само поле не можетбыть переназначенным.Это похоже на T *const
или T&
в C ++.Вы можете изменить ссылочный объект по желанию через его членов.
class Foo { public int x; }
class Bar { public readonly Foo y = new Foo(); }
Bar a = new Bar();
a.y.x = 3; // valid
a.y = new Foo(); // invalid
Ну, я не говорю всей правды.Вы можете обманывать и изменять readonly
поля с помощью отражения 1 :
typeof(string).GetField("Empty").SetValue(null, "bar");
// this effectively makes string.Empty equal to "bar", with disastrous consequences
// It requires full trust though.
// Obviously, it's evil.
Однако, если это поле const
, даже этот трюк не сработает.
const
поля жестко закодированы в сборках, которые их используют, вместо сохранения ссылок на исходную сборку:
// Assembly A.dll
public class Foo { public static const int X = 42; }
// Assembly B.dll
int y = Foo.X;
// this is the equivalent to:
int y = 42;
Это означает, что если вы перекомпилируете A.dll и измените значениеот Foo.X
до 23, B.dll все равно будет использовать 42, пока не будет перекомпилировано.
Все, что сказано, если вы хотите иметь поле, которое вы хотите изменить, просто не делайте его readonly
.Если вы хотите, чтобы класс был изменяемым, но неизменным извне, сделайте его закрытым и добавьте свойство только для чтения (примечание: это не то же самое, что поле readonly
):
class Foo
{
private int bar;
public int Bar
{
get { return bar; }
}
}
1 Этот на самом деле не гарантируется , но он работает на реализациях Microsoft.Если вам интересно, почему этот хак вообще работает, вы можете прочитать объяснение Эрика Липперта .Обязательно прочтите также ответ о readonly
для типов значений .И само собой разумеется, не делайте этого дома .