c# - XML deserialization सूची में जोड़ता है




properties xml-serialization (2)

मैं एक XML फ़ाइल से कुछ सेटिंग्स deserialize कोशिश कर रहा हूँ समस्याग्रस्त संपत्ति / अंतर्निहित क्षेत्र को एक AlertColors कहा जाता है मैं अंतर्निहित क्षेत्र को सफ़ेद, पीला, और लाल के लिए प्रारंभ करता हूं ताकि यह सुनिश्चित हो सके कि इस क्लास का एक नया उदाहरण एक वैध रंग सेटिंग है। लेकिन जब मैं deserialize, _colorArgb छह मानों के साथ समाप्त होता है, पहले तीन प्रारंभिक मूल्य हैं और अंतिम तीन जो xml फ़ाइल से पढ़े जाते हैं लेकिन संपत्ति AlertColors क्षेत्र के लिए संलग्न नहीं है, लेकिन इसके तत्वों में परिवर्तन। मैं छह रंगों के साथ एक क्षेत्र के साथ क्यों समाप्त होता है?

यहां कोड है:

    private List<int> _colorArgb = new List<int>(new int[] { Color.White.ToArgb(), Color.Yellow.ToArgb(), Color.Red.ToArgb() });   

    public List<int> AlertColors
    {
        get
        {
            return _colorArgb;
        }

        set
        {
            for (int i = 0; i < Math.Min(_colorArgb.Count, value.Count); i++)
            {
                if (_colorArgb[i] != value[i])
                {
                    HasChanged = true;
                }
            }

            _colorArgb = value;
        }
    }

    public bool Deserialize(string filePath)
    {
        if (!File.Exists(filePath))
        {
            Logger.Log("Error while loading the settings. File does not exist.");

            return false;
        }

        FileStream fileStream = null;

        try
        {
            fileStream = new FileStream(filePath, FileMode.Open);
            System.Xml.Serialization.XmlSerializerFactory xmlSerializerFactory =
                new XmlSerializerFactory();
            System.Xml.Serialization.XmlSerializer xmlSerializer =
                xmlSerializerFactory.CreateSerializer(typeof(Settings));

            Settings deserializedSettings = (Settings)xmlSerializer.Deserialize(fileStream);

            GetSettings(deserializedSettings);

            Logger.Log("Settings have been loaded successfully from the file " + filePath);
        }
        catch (IOException iOException)
        {
            Logger.Log("Error while loading the settings. " + iOException.Message);

            return false;
        }
        catch (ArgumentException argumentException)
        {
            Logger.Log("Error while loading the settings. " + argumentException.Message);

            return false;
        }
        catch (InvalidOperationException invalidOperationException)
        {
            Logger.Log("Error while loading the settings. Settings file is not supported." +
                invalidOperationException.Message);

            return false;
        }
        finally
        {
            if (fileStream != null)
                fileStream.Close();

            FilePath = filePath;
        }

        return true;
    }

    protected void GetSettings(Settings settings)
    {
        AlertColors = settings.AlertColors;
    }

और एक्सएमएल फ़ाइल का वह प्रासंगिक भाग जिसे मैं deserializing कर रहा हूं:

  <AlertColors>
    <int>-1</int>
    <int>-15</int>
    <int>-65536</int>
  </AlertColors>

अपने डेटा प्रकार को बदलने के बिना अपना वांछित परिणाम प्राप्त करने के लिए, आप सामान्य XmlSerializer के बजाय एक DataContractSerializer (System.Runtime.Serialization;) का उपयोग कर सकते हैं। यह डिफ़ॉल्ट कन्स्ट्रक्टर को कॉल नहीं करता है, इसलिए आप 6 के बजाय 3 रंगों के साथ समाप्त होंगे।

var ser = new DataContractSerializer(typeof(Settings));
var reader = new FileStream(@"c:\SettingsFile.xml", FileMode.Open);
var deserializedSettings = (Settings)ser.ReadObject(reader);

असल में, यह बस कैसे XmlSerializer काम करता है जब तक यह सूची null नहीं है, तब तक यह अपेक्षा नहीं की जाती है कि वह मूल्य सेट करे। विशेष रूप से, ज्यादातर समय, उप-आइटम सूचियों में सेटर नहीं होता है - वे ये हैं:

private readonly List<Child> children = new List<Child>();
public List<Child> Children { get { return children; } }

(क्योंकि ज्यादातर लोग बाहरी कॉल करने वालों को सूची को फिर से असाइन करने के लिए नहीं चाहते हैं, वे सिर्फ सामग्री को बदलने के लिए चाहते हैं)।

इस वजह से, XmlSerializer मूल रूप से (अधिक सरलीकरण) की तरह संचालित होता है:

var list = yourObj.SomeList;
foreach({suitable child found in the data})
    list.Add({new item});

एक फिक्स एक सूची के बजाय एक सरणी का उपयोग करना है; यह हमेशा एक सरणी वापस ऑब्जेक्ट को आवंटित करने की अपेक्षा करता है, इसलिए एक सरणी के लिए इसे और अधिक (अधिक सरलीकृत) लागू किया जाता है:

var list = new List<SomeType>();
foreach({suitable child found in the data})
    list.Add({new item});
yourObj.SomeList = list.ToArray();

हालांकि, निश्चित मानों के लिए, एक सरल कार्यान्वयन सिर्फ हो सकता है:

public Foo Value1 {get;set;}
public Foo Value2 {get;set;}
public Foo Value3 {get;set;}

(आप समझते हैं कि मेरा क्या तात्पर्य है)





xmlserializer