Сохранить сериализуемый объект в реестр в .net?

Я пишу код С# .net, который сохраняет некоторые значения в реестре. Он работал нормально, пока я не захотел сохранить некоторые двоичные данные.

У меня есть объект List<MyType>, где MyType выглядит так:

[Serializable] public class MyType
{
 public string s {get;set;}
 public string t {get;set;}
}

Я получаю сообщение об ошибке со следующим кодом:

List<MyType> objectToSaveInRegistry = getList();
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(MySpecialKey, true);
registryKey.SetValue("MySpecialValueName", objectToSaveInRegistry , RegistryValueKind.Binary);

Ошибка: «Тип объекта значения не соответствует указанному в реестре ValueKind или объект не может быть правильно преобразован».

Что я могу сделать, чтобы сохранить свой объект в реестре?


person Vivian River    schedule 20.12.2011    source источник
comment
Почему вы хотите сохранить его в реестре? Почему бы не сделать его в виде XML-файла и не сохранить?   -  person Srinivas Reddy Thatiparthy    schedule 20.12.2011
comment
@Srinivas, мой объект содержит информацию о конфигурации приложения, которое я разрабатываю. Разве реестр Windows не предназначен для сохранения настроек приложений?   -  person Vivian River    schedule 20.12.2011
comment
Вы пытаетесь передать List‹MyType› методу, который, по сути, ожидает массив байтов. Вам нужно будет преобразовать свой список в такое представление (либо путем сериализации в MemoryStream, либо с помощью другого сериализатора).   -  person Joe    schedule 20.12.2011


Ответы (3)


Возможно, сначала вам потребуется сериализовать объект с помощью файла BinaryFormatter и сохранить его в массиве byte, который затем можно передать в SetValue. Я сомневаюсь, что SetValue будет сериализовать объект для вас.

Быстрый пример:

using (var ms = new MemoryStream())
{
    var formatter = new BinaryFormatter();
    formatter.Serialize(ms, objectToSaveInRegistry);
    var data = ms.ToArray();
    registryKey.SetValue("MySpecialValueName", data, RegistryValueKind.Binary);
}
person ChrisWue    schedule 20.12.2011
comment
@ChrisWue попробуйте это ms.WriteByte(1); Console.WriteLine(ms.GetBuffer().Length + " " + ms.ToArray().Length) Вывод: 256 1 - person L.B; 20.12.2011

Лучше сериализовать/десериализовать ваш объект как строку. В следующем примере я использую сериализацию XML. Переменная «значение» — это объект списка для хранения в реестре.

// using Microsoft.Win32;
// using System.IO;
// using System.Text;
// using System.Xml.Serialization;

string objectToSaveInRegistry;

using(var stream=new MemoryStream())
{
    new XmlSerializer(value.GetType()).Serialize(stream, value);
    objectToSaveInRegistry=Encoding.UTF8.GetString(stream.ToArray());
}

var registryKey=Registry.LocalMachine.OpenSubKey("MySpecialKey", true);
registryKey.SetValue("MySpecialValueName", objectToSaveInRegistry, RegistryValueKind.String);
person CedX    schedule 20.12.2011

Я бы сохранил примитивные значения, а затем гидратировал бы poco, когда данные извлекаются, в отличие от сохранения самого poco.

person Jason Meckley    schedule 20.12.2011
comment
О чем ты говоришь? - person IS4; 08.03.2014
comment
@ IllidanS4: Он сохранял отдельные свойства объекта в виде отдельных ключей, а затем перестраивал объект из этих ключей, а не сохранял сериализованный объект в одном ключе. Преимущество будет заключаться в том, что вы можете легко манипулировать отдельными свойствами (при условии, что вы сопоставляете все вплоть до примитивных типов), хотя это также можно рассматривать как недостаток. - person ChrisWue; 31.01.2018
comment
@ChrisWue И четыре года спустя я так и не понял бы текст ответа. Хороший! - person IS4; 31.01.2018