Преимущества [NonSerialized], когда [Serializable] не используется

Я просматриваю некоторый существующий код в проекте, над которым я работаю, и нашел класс, который реализован как:

public class ThingOne
{
    private int A;

    private int B;

    [NonSerialized]
    private System.Timers.Timer timer1;
}

Разве это не должно выглядеть больше так?

[Serializable]
public class ThingOne
{
    private int A;

    private int B;

    [NonSerialized]
    private System.Timers.Timer timer1;
}

Или есть какое-то дополнительное преимущество для добавления [NonSerialized], даже если сам класс не является Сериализуемым?

5 ответов

Решение

NonSerialized не будет иметь эффекта, если Serializable не используется. По умолчанию классы и их члены не являются сериализуемыми.

Единственное преимущество объявления чего-либо NonSerialized, когда класс не сериализован, заключается в том, что класс наследуется сериализованным объектом, и тогда унаследованный член не будет сериализуемым.

Из MSDN:

Атрибут "NonSerialized" не повлияет на этот элемент, поскольку содержащий его класс не отображается как "Serializable".

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

Или есть какое-то дополнительное преимущество для добавления [NonSerialized], даже если сам класс не является Сериализуемым?

Класс не запечатан, поэтому другой класс может наследовать от этого объекта. Этот класс может быть помечен как Serializable, и тогда в игру вступит атрибут NotSerializable. (хотя, как указано, не для частных членов).

Помните, что вы можете проверить атрибуты по отражению тоже. Он может не использоваться средой выполнения для проверки того, что должно и не должно быть сериализовано, его можно использовать как маркер для чего-то другого в программе, имеющей дело с какой-то пользовательской сериализацией (я не говорю, что это хорошая идея в в мере).

Я могу думать о двух причинах:

  1. Может быть жизненно важно, чтобы поле не было сериализовано. Следовательно, если в будущем класс станет сериализуемым, это не приведет к ошибке, неэффективности или безопасности, потому что без маркировки класс serialisable также сделает это для поля.

  2. Они могут делать какое-то пользовательское использование атрибута

В случае 2 из кода будет ясно, что это то, что происходит. Номер 1 - хорошая практика.

Случай 1 - хорошая практика, может быть, стоит уравновесить YAGNI ("Вам это не нужно" - не выполнять работу "на тот случай, если это понадобится позже") с учетом "хорошо, но если мне это понадобится позже, это будет быть бедствием, если кто-то пропустит, что это поле является исключением.

Таким образом, хотя здесь это не имеет никакого эффекта, это определенно хорошая практика для сценариев, в которых он начинает оказывать влияние.

Редактировать: Другая возможность состоит в том, что это отрывок от предыдущей версии, где он был действительно сериализуемым, или автор был в двух умах в то время, и он никогда не был полностью "закончен" (рабочий код когда-либо был полностью закончен?). То, что в коде что-то есть, не означает, что так должно быть. Тем не менее, если действительно важно, чтобы что-то не было сериализовано, я все же говорю, что стоит пометить это по причине, указанной выше.

MSDN SerializeAttribute утверждает, что "Примените атрибут SerializableAttribute к типу, чтобы указать, что экземпляры этого типа могут быть сериализованы". Это означает, что без него класс не может быть сериализован. Я полагаю, что я попытался это сделать, и сериализация выдаст исключение, если будет предпринята попытка использовать тип NonSerializable.

Я согласен с Грегом, MSDN заявляет об этом аналогичным образом, цитирование ссылок - хорошая идея.

"По умолчанию классы и их члены не сериализуемы. Атрибут NonSerializedAttribute необходим, только если член сериализуемого класса не должен быть сериализован".

http://msdn.microsoft.com/en-us/library/dwys85sk(VS.80).aspx

Другие вопросы по тегам