C # — Почему перечисляемый сериализуем для T, которые не сериализуемы?

#c# #serialization

#c# #сериализация

Вопрос:

До сих пор я считал typeof(T).IsSerializable , что это верно, если T имеет атрибут [Serializable] . (И не имеет отношения к сбивающему с толку названию ISerializable ).
Это первое предположение неверно; IsSerializable кажется, оно более сложное, и я не понимаю, для чего оно предназначено.

Примеры, где IsSerializable это true, но тип не является сериализуемым:

 using NUnit.Framework;

[TestFixture]
internal class Tests {

    private class MyClass {}

    [Test]
    public void TestIsNotSerialisable()
    {
        // Passes
        Assert.That(typeof(MyClass).IsSerializable, Is.False);
    }

    [Test]
    public void TestIsNotSerialisableArray()
    {
        // Fails (is Serializable)
        Assert.That(typeof(MyClass[]).IsSerializable, Is.False);
    }

    [Test]
    public void TestIsNotSerialisableList()
    {
        // Fails (is Serializable)
        Assert.That(typeof(List<MyClass>).IsSerializable, Is.False);
    }
}
  

MSDN для IsSerializable .

Так почему же T[] сериализуема, даже если T это не так?

Комментарии:

1. List<T> Будет считаться сериализуемым, если T сериализуемо, но один из T типов свойств не является? Что вы собираетесь делать с ответами на этот вопрос? Какую проблему вы пытаетесь решить?

Ответ №1:

Ссылка MSDN, которой вы поделились, объясняет это в разделе «Примечания«:

Если текущий тип представляет сконструированный универсальный тип, это свойство применяется к определению универсального типа, из которого был сконструирован тип. Например, если текущий тип представляет MyGenericType (MyGenericType(от Integer) в Visual Basic), значение этого свойства определяется MyGenericType .

So List<T> считается сериализуемым, даже если вы можете создавать из него универсальные типы, которые не сериализуемы, и IsSerializable свойство этого не отражает.

Комментарии:

1. Хороший момент 🙂 Бьюсь об заклад, ответ на этот вопрос похож — хотя массивы не являются универсальными типами, они ведут себя как универсальный тип, а «базовая реализация» массива сериализуема. Однако я не могу найти никакой документации по ним.

Ответ №2:

Существует разница между IsSerializable, являющимся истинным, и фактической возможностью сериализации объекта без проблем во время выполнения. Поскольку список сериализуем, флаг IsSerializable всегда установлен. Однако, если вы посмотрите на UnderlyingSystemType , вы увидите, что MyClass не сериализуем.

 public void TestIsNotSerialisableList()
{
    Assert.That(typeof(List<MyClass>).UnderlyingSystemType.IsSerializable, Is.False);
}