Как я узнаю, неизменен ли класс в C#?

Вот уродливый ...

>>> import struct
>>> bin(struct.unpack('!i',struct.pack('!f',1.0))[0])
'0b111111100000000000000000000000'

В принципе, я просто использовал структурный модуль для преобразования float в int ...


Вот немного лучше, используя ctypes:

>>> import ctypes
>>> bin(ctypes.c_uint.from_buffer(ctypes.c_float(1.0)).value)
'0b111111100000000000000000000000'

В принципе, я создаю float и использую ту же ячейку памяти, но я помещаю ее как c_uint. Значение c_uint представляет собой целое число python, на которое вы можете использовать встроенную функцию bin.

16
задан Erik Forbes 27 January 2009 в 00:19
поделиться

6 ответов

Существует ImmutableObjectAttribute, но это редко используется и плохо поддерживается - и конечно не осуществляется (Вы могли отметить изменяемый объект с [ImmutableObject(true)]. AFAIK, единственная вещь это, на которое это влияет, является путем атрибуты дескрипторов IDE (т.е. показать / не-шоу именованные опции свойств).

В действительности, необходимо было бы проверить эти FieldInfo.IsInitOnly, но это только относится к действительно 100%-м неизменным типам (принимающий отражательное злоупотребление, и т.д.); это не помогает с неизменностью фруктового мороженого, ни вещами, которые неизменны на практике, но не в их реализации; т.е. они не могут быть заставлены быть публично изменяемыми, но в теории поддержка объектов это.

классическим примером А здесь была бы строка... все "знают", что string неизменно..., конечно, StringBuilder делает , видоизменяют строку под шляпой. Нет, серьезно...

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

32
ответ дан 30 November 2019 в 16:14
поделиться

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

class Foo
{
    public readonly int X
    public readonly int Y
    public Foo(int x, int y, Bar bar)
    {
        this.X = x; 
        bar.ShowYourself(this);
        this.Y = y;
        bar.ShowYourself(this);
    }
}

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

Примечание, которому, даже если все поля являются отражением только для чтения, позволяют изменить поля.

Проверка методы set на свойствах будет очень плохой эвристикой действительно.

3
ответ дан 30 November 2019 в 16:14
поделиться

Часть проблемы - то, что "неизменный" может иметь разные значения. Возьмите, например, ReadOnlyCollection< T>.

Мы склонны полагать, что это неизменно. Но что, если это - ReadOnlyCollection< SomethingChangeable>? кроме того, так как это - действительно просто обертка вокруг IList, в котором я передаю конструктору, что, если я изменяю исходный IList?

А хороший подход мог бы быть должен создать атрибут с именем как ReadOnlyAttribute и классы метки, которые Вы считаете только для чтения с ним. Для классов Вы не управляете, можно также вести список известных типов, которые Вы считаете неизменными.

РЕДАКТИРОВАНИЕ: Для некоторых хороших примеров различных типов неизменности считайте этот ряд регистраций Eric Lippert: http://blogs.msdn.com/ericlippert/archive/2007/11/13/immutability-in-c-part-one-kinds-of-immutability.aspx

3
ответ дан 30 November 2019 в 16:14
поделиться

К моему знанию, если это явно не документируется, нет никакого способа определить, неизменен ли класс или не в C#.

можно, однако, использовать Отражение для проверки на существование Методов set на свойствах; однако, отсутствие методов set не гарантирует неизменность, поскольку внутреннее состояние может изменить значения этих свойств, можно ли явно установить их или нет.

Кроме того, проверка флаг 'IsInitOnly' для полей всего класса, снова с помощью Отражения, могла бы указать на неизменность, но это не гарантирует это.

Редактирование: Вот подобный вопрос , спрошен относительно языка Java, ответ которого также применяется здесь.

2
ответ дан 30 November 2019 в 16:14
поделиться

С помощью кода я не уверен, но afaik при рассмотрении IL другого неизменного типа такого как строка, Вы будете не , видят newobj инструкция IL (Вы будете видеть ldstr для строк), возможно, осматривание IL создания может быть одним способом сказать, просто предположение...

1
ответ дан 30 November 2019 в 16:14
поделиться

Единственная справка, которую Вы получаете от времени выполнения, - то, если все поля в классе аннотируются "только для чтения". [Отредактируйте, см. @ShuggyCoUk], И даже затем CLR позволит Вам переписать его. Я просто проверил его. Тьфу.

можно получить объекты FieldInfo от класса через отражение и проверить IsInitOnly.

1
ответ дан 30 November 2019 в 16:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: