Прежде всего, атрибут Serializable
не используется для сериализации конструктора. При сериализации объектов конструктор сериализует файл ресурсов, когда не знает, как записать его в код конструктора. Это записывает его в resx как большой двоичный объект, используя InstanceDescriptor
для конструктора типа объекта по умолчанию (при этом теряются все значения свойств, которые вы, возможно, также захотите включить). Это то, что происходит со свойством Blobs
, так как дизайнер не очень хорошо сериализует универсальные списки (хотя он знает, как сериализовать массивы).
Чтобы сохранить информацию внутри этих постоянных объектов, вам нужно создать TypeConverter
, который определяет другой конструктор в InstanceDescriptor
(тот, который фактически принимает некоторое состояние для описания свойств, например ваше свойство Blobs
). Например, если вы добавили конструктор к вашему типу BasicComponent
, который принимает IEnumerable<Blob>
, вы можете получить InstanceDescriptor
для этого конструктора, передав массив Blob
s (вы создаст новый List<Blob>
вокруг этого в конструкторе). Поскольку разработчик знает, как сохранить в коде InstanceDescriptor
, и поскольку он знает, как сохранить массивы в коде, он добавил бы это в код своего разработчика, а не в resx.
Вы также можете реализовать CodeDomSerializer
, чтобы указать код, который используется для описания вашего экземпляра, который дизайнер может использовать для сохранения вашего объекта в коде дизайнера, а не в resx.
Тип преобразователя
Чтобы использовать подход с преобразователем типов, вы можете сделать что-то вроде этого:
public class BasicComponentTypeConverter : TypeConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
bool canConvert = base.CanConvertTo(context, destinationType);
if (!canConvert &&
(destinationType == typeof(InstanceDescriptor))
{
canConvert = true;
}
return canConvert;
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
object conversion = null;
if (culture == null)
{
culture = CultureInfo.CurrentCulture;
}
BasicComponent component = value as BasicComponent;
if (basicComponent != null)
{
if (destinationType == typeof(InstanceDescriptor))
{
// Note that we convert the blobs to an array as this makes for nicer persisted code output.
// Without it, we might just get a resource blob which is not human-readable.
conversion = new InstanceDescriptor(
typeof(BasicComponent).GetConstructor(new Type[] { typeof(IEnumerable<Blob>) }),
new object[] { basicComponent.Blobs.ToArray() },
true);
}
}
if (conversion == null)
{
conversion = base.ConvertTo(context, culture, value, destinationType);
}
return conversion;
}
}
Обратите внимание, что вам может понадобиться написать конвертер типов для типа Blob
. Чтобы присоединить преобразователь типа к типу, просто объявите атрибут TypeConverter
в классе, который преобразователь типа будет преобразовывать, т.е. BasicConverter для приведенного выше примера.