एप्लीकेशन सेटिंग में int [] एरे को कैसे स्टोर करें


93

मैं C # एक्सप्रेस 2008 का उपयोग करके एक साधारण विंडोज़ फ़ॉर्म एप्लिकेशन बना रहा हूं। मैं एक अनुभवी C ++ डेवलपर हूं, लेकिन मैं C # और .NET के लिए बहुत अधिक नया हूं।

मैं वर्तमान में सेटिंग डिज़ाइनर और कोड का उपयोग करके अपनी कुछ सरल एप्लिकेशन सेटिंग संग्रहीत कर रहा हूं:

// Store setting  
Properties.Settings.Default.TargetLocation = txtLocation.Text;  
...  
// Restore setting  
txtLocation.Text = Properties.Settings.Default.TargetLocation;  

अब मैं एक सेटिंग के रूप में या तो ints ( int[]), या संभवतः ints ( List< int >) की एक सूची संग्रहीत करना चाहता हूं । हालाँकि, मैं यह पता नहीं लगा सकता कि यह कैसे करना है। मैंने दस्तावेज़ीकरण, स्टैकओवरफ़्लो और Google खोज लिया है, और मुझे यह कैसे करना है, इसका एक अच्छा विवरण नहीं मिल रहा है।

मेरे द्वारा पाया गया विरल उदाहरणों के आधार पर मेरा कूबड़ यह है कि मुझे एक ऐसी श्रेणी बनानी होगी जो क्रमबद्ध हो जो मेरे सरणी या सूची को लपेटे और फिर मैं उस प्रकार का उपयोग सेटिंग्स डिज़ाइनर में कर सकूंगा। हालांकि, मुझे यकीन नहीं है कि यह कैसे करना है।

जवाबों:


137

एक और समाधान भी है - सेटिंग्स फ़ाइल के मैनुअल संपादन के लिए थोड़ी सी आवश्यकता होती है, लेकिन बाद में वीएस वातावरण और कोड में ठीक काम करता है। और कोई अतिरिक्त कार्य या रैपर की आवश्यकता नहीं है।

बात यह है कि, वीएस int[]सेटिंग्स फ़ाइल में डिफ़ॉल्ट रूप से टाइप करने की अनुमति देता है - यह आपको डिफ़ॉल्ट रूप से इसे चुनने की अनुमति नहीं देता है। तो, वांछित नाम (जैसे SomeTestSetting) के साथ एक सेटिंग बनाएं और इसे किसी भी प्रकार (जैसे stringडिफ़ॉल्ट रूप से) बनाएं । परिवर्तनों को सुरक्षित करें।

अब अपने प्रोजेक्ट फ़ोल्डर में जाएं और टेक्स्ट एडिटर (नोटपैड, उदाहरण के लिए) के साथ "Properties \ Settings.settings" फ़ाइल खोलें या आप समाधान एक्सप्लोरर में राइट क्लिक करके VS में इसे खोल सकते हैं -> गुण -> Settings.settings "," ओपन विथ ... "चुनें और फिर" XML एडिटर "या" सोर्स कोड (टेक्स्ट) एडिटर "चुनें। खोली गई xml सेटिंग में अपनी सेटिंग खोजें (यह इस तरह दिखेगा):

<Setting Name="SomeTestSetting" Type="System.String" Scope="User">
  <Value Profile="(Default)" />
</Setting>

से "प्रकार" परम बदलें System.Stringकरने के लिए System.Int32[]। अब यह खंड इस तरह दिखेगा:

<Setting Name="SomeTestSetting" Type="System.Int32[]" Scope="User">
  <Value Profile="(Default)" />
</Setting>

अब परिवर्तन सहेजें और प्रोजेक्ट सेटिंग्स फिर से खोलें - Voilà! - हमारे पास सेटिंग SomeTestSetting प्रकार के साथ System.Int32[]पहुँचा जा सकता है और इसे VS सेटिंग्स डिज़ाइनर (मानों) के माध्यम से और साथ ही कोड में संपादित किया जा सकता है।


5
बहुत बढ़िया। विज़ुअल स्टूडियो में संपादक का उपयोग करके सेटिंग में कुछ दर्ज करने के लिए, आपको कुछ इस तरह पेस्ट करना चाहिए, यह एक स्ट्रिंग ऐरे के लिए है, जिसकी मुझे आवश्यकता थी? Xml संस्करण = "1.0" एन्कोडिंग = "utf-16"?> <ArrayOfString xmlns: xsi = " w3.org/2001/XMLSchema-instance " xmlns: xsd = " w3.org/2001/XMLSchema "> <string> String1 </ string> <string> String2 </ string> </ ArrayOfString>
कार्स्टन

9
+1 .. समझ में नहीं आता कि यह उत्तर क्यों स्वीकार नहीं किया गया था .. किसी अतिरिक्त कोड की आवश्यकता नहीं है (बस मौजूदा xml की एक पंक्ति को संशोधित करें) और आपको टाइप सुरक्षा और पूर्ण बनाम डिजाइनर समर्थन मिलता है!
क्रिस

1
क्रिस, धन्यवाद :) बात यह है, मैंने अपना उत्तर बहुत बाद में जोड़ा है तो मूल रूप से स्वीकृत उत्तर (लगभग एक साल बाद, वास्तव में :))। हालांकि अनुभव साझा करना :)
जेन-अरी

6
किसी भी जिज्ञासु के लिए, कॉन्फ़िगर फ़ाइल XML सिंटैक्स int[]इस तरह दिखाई देगी (बहुत मुद्रित को छोड़कर):<setting name="SomeTestSetting" serializeAs="String"><value><ArrayOfInt xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><int>1</int><int>2</int><int>3</int></ArrayOfInt></value></setting>
aaaantoine

1
सहमत, यह एक बेहतर जवाब है, इसलिए मैंने निशान बदल दिया।
sidewinderguy

40

स्टोर करने के लिए:

string value = String.Join(",", intArray.Select(i => i.ToString()).ToArray());

फिर से बनाने के लिए:

int[] arr = value.Split(',').Select(s => Int32.Parse(s)).ToArray();

संपादित करें: हाबिल सुझाव!


ठीक है, इसलिए ऐसा लगता है कि आप डेटा को एक स्ट्रिंग में मैन्युअल रूप से अनुक्रमित कर रहे हैं, और इसके विपरीत। मुझे लगता है कि यह काम करेगा, मैं डेटा को एक स्ट्रिंग सेटिंग के रूप में संग्रहीत कर सकता हूं। मैंने ऐसा कुछ करने का सोचा था, लेकिन मैं कुछ और "साफ" या "मानक" या अधिक .NET'ish की तलाश में था। मैं इसे ध्यान में रखूँगा, अगर कुछ भी बेहतर फसल न हो। धन्यवाद।
फुटपाथ

हाय, मैं तब मैके के एवेन्यू के साथ जाऊंगा! (विन्यास अनुभाग / अनुभाग समूह)
माइक ग्लीसन जूनियर क्यूटुरियर 21

मैं इसके साथ जाने वाला हूं क्योंकि यह सरल है। सभी के विचारों के लिए धन्यवाद, मुझे यकीन है कि वे सड़क पर मदद करेंगे।
sidewinderguy

2
नोट: आपको System.Linqकाम करने के लिए उपरोक्त ट्रिक के लिए अपने usings / import में जोड़ना होगा।
शॉन हैनले

11

इस परिणाम को प्राप्त करने का एक और तरीका है जो उपयोग में बहुत साफ है लेकिन अधिक कोड की आवश्यकता है। मेरा एक कस्टम प्रकार लागू करना और निम्नलिखित कोड को टाइप करना संभव है:

List<int> array = Settings.Default.Testing;
array.Add(new Random().Next(10000));
Settings.Default.Testing = array;
Settings.Default.Save();

इसे प्राप्त करने के लिए आपको एक प्रकार के कनवर्टर के साथ एक प्रकार की आवश्यकता होती है जो स्ट्रिंग से और इसमें रूपांतरण की अनुमति देता है। आप TypeConverterAttribute के साथ प्रकार को सजाने के द्वारा ऐसा करते हैं:

[TypeConverter(typeof(MyNumberArrayConverter))]
public class MyNumberArray ...

फिर इस प्रकार के कन्वर्टर को टाइपकोर्टर के व्युत्पत्ति के रूप में लागू करना:

class MyNumberArrayConverter : TypeConverter
{
    public override bool CanConvertTo(ITypeDescriptorContext ctx, Type type)
    { return (type == typeof(string)); }

    public override bool CanConvertFrom(ITypeDescriptorContext ctx, Type type)
    { return (type == typeof(string)); }

    public override object ConvertTo(ITypeDescriptorContext ctx, CultureInfo ci, object value, Type type)
    {
        MyNumberArray arr = value as MyNumberArray;
        StringBuilder sb = new StringBuilder();
        foreach (int i in arr)
            sb.Append(i).Append(',');
        return sb.ToString(0, Math.Max(0, sb.Length - 1));
    }

    public override object ConvertFrom(ITypeDescriptorContext ctx, CultureInfo ci, object data)
    {
        List<int> arr = new List<int>();
        if (data != null)
        {
            foreach (string txt in data.ToString().Split(','))
                arr.Add(int.Parse(txt));
        }
        return new MyNumberArray(arr);
    }
}

MyNumberArray वर्ग पर कुछ सुविधा विधियाँ प्रदान करके हम सुरक्षित रूप से और सूची से असाइन कर सकते हैं, पूरा वर्ग कुछ देखेगा:

[TypeConverter(typeof(MyNumberArrayConverter))]
public class MyNumberArray : IEnumerable<int>
{
    List<int> _values;

    public MyNumberArray() { _values = new List<int>(); }
    public MyNumberArray(IEnumerable<int> values) { _values = new List<int>(values); }

    public static implicit operator List<int>(MyNumberArray arr)
    { return new List<int>(arr._values); }
    public static implicit operator MyNumberArray(List<int> values)
    { return new MyNumberArray(values); }

    public IEnumerator<int> GetEnumerator()
    { return _values.GetEnumerator(); }
    IEnumerator IEnumerable.GetEnumerator()
    { return ((IEnumerable)_values).GetEnumerator(); }
}

अंत में, सेटिंग्स में इसका उपयोग करने के लिए आप उपरोक्त वर्गों को एक विधानसभा में जोड़ते हैं और संकलन करते हैं। अपने Settings.settings संपादक में आप बस "ब्राउज़ करें" विकल्प पर क्लिक करें और MyNumberArray वर्ग का चयन करें और आप से दूर जाएं।

फिर से यह एक बहुत अधिक कोड है; हालाँकि, यह एक साधारण सरणी की तुलना में बहुत अधिक जटिल प्रकार के डेटा पर लागू किया जा सकता है।


धन्यवाद यह दिलचस्प लग रहा है। मौका मिलने पर मैं इसे आजमाऊंगा।
sidewinderguy

3

एक System.Collections.ArrayList के रूप में सेटिंग निर्दिष्ट करें और फिर:

Settings.Default.IntArray = new ArrayList(new int[] { 1, 2 });

int[] array = (int[])Settings.Default.IntArray.ToArray(typeof(int));

2

एक साधारण समाधान संपत्ति में शून्य करने के लिए एक सेटिंग का डिफ़ॉल्ट मान सेट करना है, लेकिन निर्माणकर्ता की जांच में अगर संपत्ति शून्य है और यदि ऐसा है तो इसे उसके वास्तविक डिफ़ॉल्ट मूल्य पर सेट करें। तो अगर आप एक प्रकार की स्याही चाहते हैं:

public class ApplicationSettings : ApplicationSettingsBase
{
    public ApplicationSettings()
    {
        if( this.SomeIntArray == null )
            this.SomeIntArray = new int[] {1,2,3,4,5,6};
    }

    [UserScopedSetting()]
    [DefaultSettingValue("")]
    public int[] SomeIntArray
    {
        get
        {
            return (int[])this["SomeIntArray"];
        }
        set
        {
            this["SomeIntArray"] = (int[])value;
        }
    }
}

यह एक प्रकार का हैकी लगता है, लेकिन इसका स्वच्छ और वांछित के रूप में काम करता है क्योंकि गुणों को उनके अंतिम (या डिफ़ॉल्ट) सेटिंग्स के लिए आरम्भ किया जाता है, जिसे कंस्ट्रक्टर कहा जाता है।


2
फ़ाइलों को सेट करने के लिए डिज़ाइनर कोड को ऑटोजेनरेट्स करता है, और इसलिए इस तरह से बदलाव को कभी भी डिज़ाइनर द्वारा उपयोग किए गए किसी भी व्यक्ति को अधिलेखित कर दिया जाएगा।
कार्ल जी।

1

का इस्तेमाल किया System.Object

उदाहरण:

byte[] arBytes = new byte[] { 10, 20, 30 };
Properties.Settings.Default.KeyObject = arBytes;

निकालें:

arBytes = (byte[])Properties.Settings.Default.KeyObject;

1
मैंने System.Object का उपयोग करने की कोशिश की, लेकिन सेटिंग्स सत्र के बीच जारी नहीं थी। (हाँ, यह एक रिलीज़ बिल्ड, स्टैंड-अलोन इंस्‍टॉल था, जिसे आप इसे कॉल करना चाहते हैं, मैं आईडीई का उपयोग करके डिबगिंग नहीं कर रहा था)
इमानुएल विंटिलो

0

मुझे लगता है कि आप अपनी सेटिंग्स को क्रमबद्ध करने के बारे में सही हैं। नमूने के लिए इस प्रश्न के लिए मेरा उत्तर देखें:

दो ऐप्स के बीच कॉन्फिग शेयर करने की तकनीक?

आपके पास एक संपत्ति होगी जो एक सरणी है, जैसे:

/// <summary>
/// Gets or sets the height.
/// </summary>
/// <value>The height.</value>
[XmlAttribute]
public int [] Numbers { get; set; }

0

कुछ फ़ंक्शंस करें जो एक स्ट्रिंग में एक इंट अरेंज को रूपांतरित करते हैं, लेकिन प्रत्येक के बीच "(स्पेस) जैसा एक कैरेक्टर डालते हैं।

तो अगर सरणी {1,34,546,56} है तो स्ट्रिंग "1 34 645 56" होगी

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.