如何在应用程序设置中存储int 数组

我正在使用C#express 2008创build一个简单的Windows窗体应用程序。我是一个有经验的C ++开发人员,但是我对C#和.NET几乎是全新的。

我正在使用设置devise器和代码来存储我的一些简单的应用程序设置,如下所示:

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

现在我想存储一个ints( int[] )的数组,或者可能是一个int List< int >List< int > )作为一个设置。 但是,我不知道如何做到这一点。 我搜查了文档,stackoverflow和谷歌,我找不到一个像样的解释如何做到这一点。

基于我发现的稀疏范例,我的直觉是我必须创build一个可序列化的类来包装我的数组或List,然后我将能够在设置devise器中使用该types。 但是,我不确定如何做到这一点。

在此先感谢您的帮助!

还有另一个解决scheme – 需要一些手动编辑的设置文件,但后来在VS环境和代码中正常工作。 并且不需要额外的function或包装。

事情是,VS允许在设置文件中默认序列化int[]types – 它只是不允许你默认select它。 所以,创build一个所需的名称(例如SomeTestSetting)的设置,并将其设置为任何types(例如默认情况下的string )。 保存更改。

现在进入你的项目文件夹,用文本编辑器(例如记事本)打开“Properties \ Settings.settings”文件,或者你可以在VS中打开它,方法是右键单击Solution Explorer中的“ – > Properties – > Settings.settings “,select”打开方式…“,然后select”XML编辑器“或”源代码(文本)编辑器“。 在打开的xml设置中find你的设置(它看起来像这样):

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

将“types”参数从System.String更改为System.Int32[] 。 现在这个部分将如下所示:

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

现在保存更改并重新打开项目设置 – voilà! – 我们已经设置了types为System.Int32[] SomeTestSetting,可以通过VS Settings Designer(值也可以)访问和编辑,也可以在代码中进行编辑。

储藏:

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

重新创build:

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

编辑:亚伯的build议!

还有一种方法可以达到这个结果,使用起来更加清洁,但是需要更多的代码。 我实现一个自定义的types和types转换器是可能的以下代码:

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

要实现这一点,你需要一个types转换器,允许转换和从string。 您可以通过使用TypeConverterAttribute装饰该types来完成此操作:

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

然后实现这个types转换器作为TypeConverter的派生:

 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类中提供一些便利的方法,我们可以安全地分配给List和从List中,完整的类看起来像这样:

 [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编辑器中,你只需点击“浏览”选项并selectMyNumberArray类,然后离开你。

再次,这是更多的代码; 然而,它可以应用于比简单的数组更复杂的数据types。

将该设置指定为System.Collections.ArrayList,然后:

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

一个简单的解决scheme是在属性中设置默认值为null,但是在构造函数中检查属性是否为null,如果是,则将其设置为其实际的默认值。 所以,如果你想要一个int数组:

 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; } } } 

它感觉有点不好意思,但是它的干净和工作正常,因为在调用构造函数之前,属性被初始化为它们的最后(或默认)设置。

使用System.Object

例:

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

提取:

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

我想你是正确的序列化您的设置。 查看我对这个问题的回答,获取样本:

在两个应用程序之间共享configuration的技巧?

你会有一个属性,这是一个数组,如下所示:

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

创build一些函数,将一个int数组转换成一个string,但是每个函数之间放置一个像“”(space)这样的字符。

所以如果数组是{1,34,546,56},string将是“1 34 645 56”