2009-08-18 16 views
36

क्या होता है यदि हम एक स्थिर वर्ग को क्रमबद्ध करते हैं? यदि हम इसे क्रमबद्ध करते हैं तो स्थिर वर्ग के एक से अधिक उदाहरण बनाए जा सकते हैं?एक स्टेटिक क्लास Serialize?

[Serializable] 
public static class MyClass 
{ 
    public static MyClass() 
    { 

    } 

    public static bool IsTrue() 
    { 
     return true; 
    } 
} 

मान लीजिए मैं एक एक्सएमएल फ़ाइल के लिए वस्तु XmlSerialize, और बाद में मैं वापस एक वस्तु के लिए डे-क्रमानुसार। स्मृति में एक और प्रति मौजूद है (जब किसी ने पहली बार स्थिर calss instintiated बनाया)। क्या, वस्तु की दो प्रतियां होंगी? यदि हां, तो क्या हम इसे रोक सकते हैं? क्या यह सिंगलटन पैटर्न का पालन करने वाले किसी भी वर्ग पर लागू होता है?

+0

मुझे लगता है कि "सिंगलटन" और "स्थैतिक" के बीच यहां कुछ भ्रम है ... –

+1

"मान लीजिए कि मैं एक्सएमएल ऑब्जेक्ट को व्यवस्थित करता हूं": कौन सा ऑब्जेक्ट? वहां कोई ऑब्जेक्ट नहीं है (यानी कोई उदाहरण नहीं), क्योंकि कक्षा स्थिर –

उत्तर

52

कभी भी स्थिर 0 वर्गों के स्थिर वर्गों के उदाहरण नहीं हैं: वे आईएल में अमूर्त और मुहरबंद दोनों हैं, इसलिए सीएलआर किसी भी उदाहरण को बनाएगा। इसलिए serialize करने के लिए कुछ भी नहीं है। स्थिर क्षेत्रों को कभी भी धारावाहिक नहीं किया जाता है, और यह एकमात्र ऐसा राज्य है जो स्थिर वर्ग के पास हो सकता है।

एक्सएमएल सीरियलाइजेशन के बारे में आपका प्रश्न कोई समझ नहीं आता है, क्योंकि कोई भी कभी भी स्थैतिक वर्ग के साथ शुरू करने के लिए कोई उदाहरण नहीं बना सकता है।

+1

इसके बारे में क्या: 'सार्वजनिक स्थैतिक वर्ग कॉन्स्टेंट { सार्वजनिक कॉन्स स्ट्रिंग Con1 = "con1"; सार्वजनिक कॉन्स स्ट्रिंग Con2 = "con2"; } ' मैं इसे गतिशील रूप से जावास्क्रिप्ट में पास करना चाहता हूं, उस स्थिति में क्रमबद्ध करने का कोई तरीका समझ में आता है। हां, शब्द _serialize_ का आज थोड़ा अलग अर्थ हो सकता है। –

+0

@orhor: "यह पास करें" से आपका क्या मतलब है? यदि आप "स्थिरांक का संग्रह" पास करना चाहते हैं तो आप इसे आसानी से आसानी से कर सकते हैं, लेकिन मुझे नहीं लगता कि "serialize" शब्द का सामान्य अर्थ बदलता है। –

+0

ठीक है, लिटरेली: मुझे जावास्क्रिप्ट से एक सेवा कॉल करने और सेवा की सी # प्रकार से संबंधित जावास्क्रिप्ट ऑब्जेक्ट में इसकी प्रतिक्रिया को deserialize करने की आवश्यकता है। थोड़ा अलग अर्थों से मेरा मतलब था कि उन दो विकल्पों: 1. एक _object_ (जो एक उदाहरण का तात्पर्य है) का अनुवाद एक स्टेरेट प्रारूप में 2. कुछ भी अनुवाद करना - बस मेमोरी डेटा, एक प्रकार या जो भी आप टेक्स्ट प्रारूप में चाहते हैं। उदाहरण के लिए सेवा से क्लाइंट पर कोई वेब पर स्थानांतरित करें लेकिन कोई अपराध नहीं है, कृपया, मैं आपके उत्तर का अपमान नहीं कर रहा हूं, मैं बस (उम्मीद है) उस पृष्ठ पर जानकारी के स्पेक्ट्रम को चौड़ा कर रहा हूं। और प्रश्नों के लिए धन्यवाद। –

17

आप अंतर्निहित .NET क्रमबद्धता सुविधाओं का उपयोग करके static कक्षाओं (या किसी भी वर्ग जो भी) क्रमबद्ध नहीं कर सकते हैं। आप केवल कक्षाओं के उदाहरण क्रमबद्ध कर सकते हैं।

+0

है, लेकिन क्या उपरोक्त परिदृश्य मौजूद है? यही है, क्या एक स्थिर वर्ग के एक से अधिक उदाहरण हो सकते हैं? – Bhaskar

+1

नहीं। ऐसा नहीं हो सकता है। –

12

आप निम्न वर्ग बना सकते हैं:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Runtime.Serialization.Formatters.Soap; 
using System.Reflection; 
using System.IO; 

namespace SerializeStatic_NET 
{ 
    public class SerializeStatic 
    { 
     public static bool Save(Type static_class, string filename) 
     { 
      try 
      { 
       FieldInfo[] fields = static_class.GetFields(BindingFlags.Static | BindingFlags.Public); 
       object[,] a = new object[fields.Length,2]; 
       int i = 0; 
       foreach (FieldInfo field in fields) 
       { 
        a[i, 0] = field.Name; 
        a[i, 1] = field.GetValue(null); 
        i++; 
       }; 
       Stream f = File.Open(filename, FileMode.Create); 
       SoapFormatter formatter = new SoapFormatter();     
       formatter.Serialize(f, a); 
       f.Close(); 
       return true; 
      } 
      catch 
      { 
       return false; 
      } 
     } 

     public static bool Load(Type static_class, string filename) 
     { 
      try 
      { 
       FieldInfo[] fields = static_class.GetFields(BindingFlags.Static | BindingFlags.Public);     
       object[,] a; 
       Stream f = File.Open(filename, FileMode.Open); 
       SoapFormatter formatter = new SoapFormatter(); 
       a = formatter.Deserialize(f) as object[,]; 
       f.Close(); 
       if (a.GetLength(0) != fields.Length) return false; 
       int i = 0; 
       foreach (FieldInfo field in fields) 
       { 
        if (field.Name == (a[i, 0] as string)) 
        { 
         field.SetValue(null, a[i,1]); 
        } 
        i++; 
       };     
       return true; 
      } 
      catch 
      { 
       return false; 
      } 
     } 
    } 
} 

आप System.Runtime.Serialization.Formatters.Soap के लिए एक संदर्भ परिभाषित करना होगा।

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"); 

फ़ील्ड ए, एज़, जीई नए, भारित मूल्य नहीं।

7

क्यों न केवल एक अस्थायी उदाहरण वर्ग का उपयोग करें जो स्थैतिक वर्ग का दर्पण है?

[XmlRoot] 
public class SerializeClass 
{ 
    public int Number { 
     get; 
     set; 
    } 
} 

public static class SerializedClass { 

    public static int Number { 
     get; 
     set; 
    } 


    public static void Serialize(Stream stream) { 

     SerializeClass obj = new SerializeClass(); 
     obj.Number = Number; 

     XmlSerializer serializer = new XmlSerializer(typeof(SerializeClass)); 
     serializer.Serialize(stream, obj); 
    } 

    public static void Deserialize(Stream stream) { 

     XmlSerializer serializer = new XmlSerializer(typeof(SerializeClass)); 
     SerializeClass obj = (SerializeClass)serializer.Deserialize(stream); 

     Number = obj.Number; 
    } 
} 

मैं जानता हूँ कि यह एक हैक का एक सा है, लेकिन यह एक ही उद्देश्य acheives, जबकि अभी भी रनटाइम के दौरान क्रम से पहले Refactor, और मूल्य सत्यापन की इजाजत दी।

+1

नीचे वोट के लिए कोई स्पष्टीकरण नहीं? स्टेटिक कक्षाओं को क्रमबद्ध नहीं किया जा सकता है, और यह एक स्वीकार्य काम है, मुझे आश्चर्य है कि इस परिदृश्य में प्रतिबिंब सबसे अच्छा जवाब क्यों है? इसके लिए अधिक संसाधनों की आवश्यकता होती है और डेटा को उस ऑब्जेक्ट पर कॉपी करने से बहुत धीमी होती है जिसे धाराबद्ध किया जा सकता है। हमम – SilverX

+0

प्रतिबिंब मार्ग कोड की बहुत कम लाइन है यदि आपके पास बहुत सारे वर्ग हैं, या वास्तव में, बहुत सारे फ़ील्ड वाले वर्ग हैं। – LeeCambl

0

मुझे यह जवाब मेरी सेटिंग कक्षा के लिए वास्तव में उपयोगी पाया गया है! 1000 धन्यवाद!

लेकिन मैं servicepack संगतता

public class SerializeStatic 
{ 
    public static bool Save(Type static_class, string filename) 
    { 
     try 
     { 
      FieldInfo[] fields = static_class.GetFields(BindingFlags.Static | BindingFlags.Public); 

      object[,] a = new object[fields.Length-1,2]; //one field can´t be serialized, so shouldn´t be counted 
      int i = 0; 
      foreach (FieldInfo field in fields) 
      { 
       if(field.Name == "db") continue; // db cant be serialized! so get away.. not very pretty but does its job :) 
       a[i, 0] = field.Name; 
       a[i, 1] = field.GetValue(null); 
       i++; 
      }; 
      Stream f = File.Open(filename, FileMode.Create); 
      BinaryFormatter formatter = new BinaryFormatter(); //Soapformatter -> .NET 4.5 -> doesn´t run under xp! 
      // SoapFormatter formatter = new SoapFormatter(); 
      formatter.Serialize(f, a); 
      f.Close(); 
      return true; 
     } 
     catch(Exception ex) 
     { 
      System.Windows.Forms.MessageBox.Show(ex.ToString()); //Better error messages 
      return false; 
     } 
    } 

    public static bool Load(Type static_class, string filename) 
    { 
     try 
     { 
      FieldInfo[] fields = static_class.GetFields(BindingFlags.Static | BindingFlags.Public); 
      object[,] a; 
      Stream f = File.Open(filename, FileMode.Open); 
      BinaryFormatter formatter = new BinaryFormatter(); 
      a = formatter.Deserialize(f) as object[,]; 
      f.Close(); 
      if (a.GetLength(0) != fields.Length-1) return false; 

      foreach (FieldInfo field in fields) 
       for(int i=0;i< fields.Length-1;i++) //I ran into problems that some fields are dropped,now everyone is compared to everyone, problem fixed 
        if (field.Name == (a[i, 0] as string)) 
         field.SetValue(null, a[i,1]); 
      return true; 
     } 
     catch(Exception ex) 
     { 
      System.Windows.Forms.MessageBox.Show(ex.ToString()); 
      return false; 
     } 
    } 
} 
0

एक अन्य समाधान, लेकिन एक है कि पढ़ता है और xml में लिखते हैं की वजह से यह काम कर रहे एक गैर serializable वस्तु और BinaryFormatter के लिए परिवर्तन की वजह से बनाने के लिए कुछ परिवर्तन करना था। आप धारावाहिक होने से रोकने के लिए फ़ील्ड के ऊपर [NonSerialized] विशेषता का भी उपयोग कर सकते हैं।

public static class SerializeStatic 
{ 
    public static bool Serialize(Type staticClass, string fileName) 
    { 
     XmlTextWriter xmlWriter = null; 

     try 
     { 
      xmlWriter = new XmlTextWriter(fileName, null); 

      xmlWriter.Formatting = Formatting.Indented; 

      xmlWriter.WriteStartDocument(); 

      Serialize(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(string name, object obj, XmlTextWriter xmlWriter) 
    { 
     Type type = obj.GetType(); 
     XmlAttributeOverrides xmlAttributeOverrides = new XmlAttributeOverrides(); 
     XmlAttributes xmlAttributes = new XmlAttributes(); 
     xmlAttributes.XmlRoot = new XmlRootAttribute(name); 
     xmlAttributeOverrides.Add(type, xmlAttributes); 
     XmlSerializer xmlSerializer = new XmlSerializer(type, xmlAttributeOverrides); 

     xmlSerializer.Serialize(xmlWriter, obj); 
    } 

    public static bool Serialize(Type staticClass, XmlTextWriter xmlWriter) 
    { 
     FieldInfo[] fieldArray = staticClass.GetFields(BindingFlags.Static | BindingFlags.Public); 

     xmlWriter.WriteStartElement(staticClass.Name); 

     foreach (FieldInfo fieldInfo in fieldArray) 
     { 
      if (fieldInfo.IsNotSerialized) 
       continue; 

      string fieldName = fieldInfo.Name; 
      string fieldValue = null; 
      Type 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(Type staticClass, string fileName) 
    { 
     XmlReader xmlReader = null; 

     try 
     { 
      xmlReader = new XmlTextReader(fileName); 

      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(string name, Type type, XmlReader xmlReader) 
    { 
     XmlAttributeOverrides xmlAttributeOverrides = new XmlAttributeOverrides(); 
     XmlAttributes xmlAttributes = new XmlAttributes(); 
     xmlAttributes.XmlRoot = new XmlRootAttribute(name); 
     xmlAttributeOverrides.Add(type, xmlAttributes); 
     XmlSerializer xmlSerializer = new XmlSerializer(type, xmlAttributeOverrides); 

     return xmlSerializer.Deserialize(xmlReader); 
    } 

    public static bool Deserialize(Type staticClass, XmlReader xmlReader) 
    { 
     FieldInfo[] 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 in fieldArray) 
      { 
       string fieldName = fieldInfo.Name; 
       Type 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, value); 
        } 
       } 
      } 
     } 

     return true; 
    } 
} 
संबंधित मुद्दे