Может ли C # приводить const? - PullRequest
       1

Может ли C # приводить const?

2 голосов
/ 24 августа 2011

Если объект доступен только для чтения или является постоянным, возможно ли привести его к записи? Нечто похожее на C ++ const_cast.

Ответы [ 4 ]

12 голосов
/ 24 августа 2011

Это невозможно в 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 для типов значений .И само собой разумеется, не делайте этого дома .

1 голос
/ 24 августа 2011

Нет.Ссылка или значение будут доступны только для чтения.

Однако вы можете изменить свойства ссылок или просто скопировать значение.

1 голос
/ 24 августа 2011

Вы не сможете изменить значение самого const. Все, что вы можете сделать, это взять копию и изменить ее. Если я не понимаю вопрос ...?

Имейте в виду, что в C # const является довольно ограниченным ключевым словом, вы можете объявить только определенные вещи как const и только во время компиляции:

http://msdn.microsoft.com/en-us/library/e6w8fe1b(v=VS.100).aspx

Не уверен, почему вы хотите изменить константу.

0 голосов
/ 24 августа 2011

Объекты не только для чтения или const, только переменные. Это означает, что вы можете присвоить значение такой переменной только один раз (в случае const) или только до тех пор, пока не будет создан объект-владелец (в случае readonly).

Объект, назначенный переменной readonly, все еще можно изменить, если только он не является неизменным (например, string).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...