Как работать с сериализацией списков в статическом классе? [dубликат]

для нескольких баз данных:

mysqldump -u user -p --ignore-table=db1.tbl1 --ignore-table=db2.tbl1 --databases db1 db2 ..
37
задан Bhaskar 18 August 2009 в 13:21
поделиться

6 ответов

Не существует любых экземпляров статических классов: они абстрактны и запечатаны в IL, поэтому среда CLR предотвратит создание любых экземпляров. Поэтому сериализовать нечего. Статические поля никогда не сериализуются, и это единственное состояние, которое может иметь статический класс.

Ваш вопрос о сериализации XML не имеет смысла, поскольку никто никогда не мог создать экземпляр статического класса для начала.

54
ответ дан Jon Skeet 15 August 2018 в 21:54
поделиться
  • 1
    что об этом: public static class Constants {public const string Con1 = & quot; con1 & quot ;; public const string Con2 = & quot; con2 & quot ;; } Я хотел бы динамически передать это на javascript, в этом случае имеет смысл какой-то способ сериализации. Да, слово serialize может иметь несколько разные значения сегодня. – or hor 21 April 2016 в 08:34
  • 2
    @orhor: Что вы имеете в виду под этим & quot; передать это & ​​quot ;? Если вы хотите передать & quot; коллекцию констант & quot; то вы могли бы сделать это достаточно легко, но я не думаю, что это изменяет нормальный смысл термина «сериализация». – Jon Skeet 21 April 2016 в 09:23
  • 3
    ok, literrally: мне нужно вызвать службу из javascript и десериализовать ее ответ в javascript-объект, относящийся к типу c # службы. В несколько разных значениях я имел в виду эти две альтернативы: 1. перевод object (который подразумевает экземпляр) в сохраняемый формат 2. перевод всего - просто данных памяти, типа или всего, что вы хотите в текстовый формат. Например, переносятся через сеть от службы к клиенту, но без обид, пожалуйста, я не оскорбляю ваш ответ, я просто (надеюсь) расширяю спектр информации на этой странице. И спасибо за вопросы. – or hor 21 April 2016 в 10:20
  • 4
    @orhor: Я бы предложил задать новый вопрос для вашей конкретной ситуации. То, что вы описываете, звучит широко, как «преобразование в текстовое представление». а не «сериализации». – Jon Skeet 21 April 2016 в 10:25

Я нашел этот ответ действительно полезным для моего класса настройки! 1000 благодаря вам!

Но мне пришлось сделать некоторые изменения, чтобы заставить его работать из-за объекта, не связанного с сериализацией, и изменения в BinaryFormatter из-за совместимости с servicepack

  public  class SerializeStatic {public static bool Сохранить (Тип static_class, string filename) {try {FieldInfo [] fields = static_class.GetFields (BindingFlags.Static | BindingFlags.Public);  object [,] a = новый объект [fields.Length-1,2];  // одно поле не может быть сериализовано, поэтому не следует считать int i = 0;  foreach (поле FieldInfo в полях) {if (field.Name == "db") continue;  // db не может быть сериализовано!  так что убирайся .. не очень красиво, но выполняет свою работу :) a [i, 0] = field.Name;  a [i, 1] = field.GetValue (null);  я ++;  };  Поток f = File.Open (имя файла, FileMode.Create);  BinaryFormatter formatter = new BinaryFormatter ();  // Soapformatter - & gt;  .NET 4.5 - & gt;  не работает под xp!  // SoapFormatter formatter = new SoapFormatter ();  formatter.Serialize (f, a);  f.close ();  return true;  } catch (Exception ex) {System.Windows.Forms.MessageBox.Show (ex.ToString ());  // Улучшенные сообщения об ошибках возвращают false;  }} public static bool Load (Тип static_class, string filename) {try {FieldInfo [] fields = static_class.GetFields (BindingFlags.Static | BindingFlags.Public);  object [,] a;  Поток f = File.Open (имя файла, FileMode.Open);  BinaryFormatter formatter = new BinaryFormatter ();  a = formatter.Deserialize (f) как объект [,];  f.close ();  if (a.GetLength (0)! = fields.Length-1) return false;  foreach (поле FieldInfo в полях) для (int i = 0; i & lt; fields.Length-1; i ++) // Я столкнулся с проблемами, которые некоторые поля отбрасываются, теперь все сравниваются со всеми, проблема исправлена ​​if (field.Name  == (a [i, 0] как строка)) field.SetValue (null, a [i, 1]);  return true;  } catch (Exception ex) {System.Windows.Forms.MessageBox.Show (ex.ToString ());  return false;  }}}  
0
ответ дан andi 15 August 2018 в 21:54
поделиться

Другое решение, но которое читает и записывает в xml. Вы также можете использовать атрибут [NonSerialized] над полем, чтобы предотвратить его сериализацию.

  public static class SerializeStatic {public static bool Serialize (Тип staticClass, string fileName) {XmlTextWriter xmlWriter = null  ;  try {xmlWriter = новый XmlTextWriter (fileName, null);  xmlWriter.Formatting = Formatting.Indented;  xmlWriter.WriteStartDocument ();  Сериализовать (staticClass, xmlWriter);  xmlWriter.WriteEndDocument ();  return true;  } catch (Exception ex) {System.Windows.Forms.MessageBox.Show (ex.ToString ());  return false;  } finally {if (xmlWriter! = null) {xmlWriter.Flush ();  xmlWriter.Close ();  }}} public static void Serialize (имя строки, объект obj, XmlTextWriter xmlWriter) {Тип type = obj.GetType ();  XmlAttributeOverrides xmlAttributeOverrides = новый XmlAttributeOverrides ();  XmlAttributes xmlAttributes = new XmlAttributes ();  xmlAttributes.XmlRoot = новый XmlRootAttribute (имя);  xmlAttributeOverrides.Add (тип, xmlAttributes);  XmlSerializer xmlSerializer = новый XmlSerializer (тип, xmlAttributeOverrides);  xmlSerializer.Serialize (xmlWriter, obj);  } public static bool Serialize (Тип staticClass, XmlTextWriter xmlWriter) {ПолеInfoInfo [] fieldArray = staticClass.GetFields (BindingFlags.Static | BindingFlags.Public);  xmlWriter.WriteStartElement (staticClass.Name);  foreach (FieldInfo fieldInfo в полеArray) {if (fieldInfo.IsNotSerialized) continue;  string fieldName = fieldInfo.Name;  string fieldValue = null;  Тип fieldType = fieldInfo.FieldType;  object fieldObject = fieldInfo.GetValue (fieldType);  if (fieldObject! = null) {if (fieldType.GetInterface ("IDictionary")! = null || fieldType.GetInterface ("IList")! = null) {Serialize (fieldName, fieldObject, xmlWriter);  } else {TypeConverter typeConverter = TypeDescriptor.GetConverter (fieldInfo.FieldType);  fieldValue = typeConverter.ConvertToString (fieldObject);  xmlWriter.WriteStartElement (FIELDNAME);  xmlWriter.WriteString (fieldValue);  xmlWriter.WriteEndElement ();  }}} xmlWriter.WriteEndElement ();  return true;  } public static bool Deserialize (Тип staticClass, string fileName) {XmlReader xmlReader = null;  try {xmlReader = новый XmlTextReader (имя_файла);  Deserialize (staticClass, xmlReader);  return true;  } catch (Exception ex) {System.Windows.Forms.MessageBox.Show (ex.ToString ());  return false;  } finally {if (xmlReader! = null) {xmlReader.Close ();  xmlReader = null;  }}} public static object Deserialize (имя строки, тип типа, XmlReader xmlReader) {XmlAttributeOverrides xmlAttributeOverrides = new XmlAttributeOverrides ();  XmlAttributes xmlAttributes = new XmlAttributes ();  xmlAttributes.XmlRoot = новый XmlRootAttribute (имя);  xmlAttributeOverrides.Add (тип, xmlAttributes);  XmlSerializer xmlSerializer = новый XmlSerializer (тип, xmlAttributeOverrides);  return xmlSerializer.Deserialize (xmlReader);  } public static bool Deserialize (Тип staticClass, XmlReader xmlReader) {ПолеInfoInfo [] fieldArray = staticClass.GetFields (BindingFlags.Static | BindingFlags.Public);  string currentElement = null;  while (xmlReader.Read ()) {if (xmlReader.NodeType == XmlNodeType.EndElement) continue;  if (xmlReader.NodeType == XmlNodeType.Element) {currentElement = xmlReader.Name;  } foreach (FieldInfo fieldInfo в fieldArray) {string fieldName = fieldInfo.Name;  Тип fieldType = fieldInfo.FieldType;  object fieldObject = fieldInfo.GetValue (fieldType);  if (fieldInfo.IsNotSerialized) continue;  if (fieldInfo.Name == currentElement) {if (typeof (IDictionary) .IsAssignableFrom (fieldType) || typeof (IList) .IsAssignableFrom (fieldType)) {fieldObject = Deserialize (fieldName, fieldType, xmlReader);  fieldInfo.SetValueDirect (__ makeref (fieldObject), fieldObject);  } else if (xmlReader.NodeType == XmlNodeType.Text) {TypeConverter typeConverter = TypeDescriptor.GetConverter (fieldType);  object value = typeConverter.ConvertFromString (xmlReader.Value);  fieldInfo.SetValue (fieldObject, значение);  }}}} return true;  }}  
0
ответ дан headkaze 15 August 2018 в 21:54
поделиться

Вы не можете сериализовать static классы (или любой класс вообще) с использованием встроенных функций сериализации .NET. Вы можете сериализовать экземпляры классов.

17
ответ дан Mehrdad Afshari 15 August 2018 в 21:54
поделиться
  • 1
    Но может ли такой сценарий существовать? То есть, может ли быть более одного экземпляра статического класса? – Bhaskar 18 August 2009 в 13:28
  • 2
    Неа. Этого не может быть. – Mehrdad Afshari 18 August 2009 в 13:51

Вы можете создать следующий класс:

  с помощью System;  используя System.Collections.Generic;  используя System.Linq;  используя System.Text;  используя System.Runtime.Serialization.Formatters.Soap;  используя System.Reflection;  используя System.IO;  namespace SerializeStatic_NET {public class SerializeStatic {public static bool Сохранить (Тип static_class, имя_файла) {try {FieldInfo [] fields = static_class.GetFields (BindingFlags.Static | BindingFlags.Public);  object [,] a = новый объект [fields.Length, 2];  int i = 0;  foreach (поле FieldInfo в полях) {a [i, 0] = field.Name;  a [i, 1] = field.GetValue (null);  я ++;  };  Поток f = File.Open (имя файла, FileMode.Create);  SoapFormatter formatter = new SoapFormatter ();  formatter.Serialize (f, a);  f.close ();  return true;  } catch {return false;  }} public static bool Load (Тип static_class, string filename) {try {FieldInfo [] fields = static_class.GetFields (BindingFlags.Static | BindingFlags.Public);  object [,] a;  Поток f = File.Open (имя файла, FileMode.Open);  SoapFormatter formatter = new SoapFormatter ();  a = formatter.Deserialize (f) как объект [,];  f.close ();  if (a.GetLength (0)! = fields.Length) return false;  int i = 0;  foreach (поле FieldInfo в полях) {if (field.Name == (a [i, 0] как строка)) {field.SetValue (null, a [i, 1]);  } i ++;  };  return true;  } catch {return false;  }}}}  

Вы должны определить ссылку на System.Runtime.Serialization.Formatters.Soap.

Скажите, что в вашей программе вы хотите сохранить следующие статические class:

  public static class A {public static string s;  public static int i;  public static double z;  }  

Вы можете использовать следующий код:

  bool ok = SerializeStatic.Save (typeof (A), "c: \\ tests \\ a  .dat ");   

Если вы хотите загрузить сохраненные данные (в той же программе или в другую программу), используйте следующий код:

  bool ok2 = SerializeStatic.  Load (typeof (A), "c: \\ tests \\ a.dat");   

Поля A.s, A.i, A.z получат новые загруженные значения.

12
ответ дан Mikhail Semenov 15 August 2018 в 21:54
поделиться

Почему бы просто не использовать временный класс экземпляра, который является зеркалом статического класса?

  [XmlRoot] public class SerializeClass {public int Number {get;  задавать;  }} public static class SerializedClass {public static int Number {get;  задавать;  } public static void Serialize (поток потока) {SerializeClass obj = new SerializeClass ();  obj.Number = Number;  XmlSerializer serializer = новый XmlSerializer (typeof (SerializeClass));  serializer.Serialize (поток, obj);  } public static void Deserialize (поток потока) {XmlSerializer serializer = новый XmlSerializer (typeof (SerializeClass));  SerializeClass obj = (SerializeClass) serializer.Deserialize (поток);  Number = obj.Number;  }}  

Я знаю, что это немного взломанный, но он имеет ту же цель, но до сих пор разрешает Рефактору до выполнения, и проверяет ценность во время выполнения.

7
ответ дан SilverX 15 August 2018 в 21:54
поделиться
  • 1
    Нет объяснений для голосования? Статические классы не могут быть сериализованы, и это приемлемая работа, мне интересно, почему размышление - лучший ответ в этом сценарии? Он требует больше ресурсов и намного медленнее, чем просто копирование данных в объект, который может быть сериализован. хммм – SilverX 23 August 2013 в 21:49
  • 2
    Маршрут отражения намного меньше строк кода, если у вас много классов или, действительно, классы с большим количеством полей. – LeeCambl 2 March 2015 в 16:04
Другие вопросы по тегам:

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