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

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

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

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

现在我想存储一个int数组( int[] ),或者可能存储一个int ListList )作为设置。 但是,我无法弄清楚如何做到这一点。 我搜索了文档,stackoverflow和谷歌,我找不到如何做到这一点的体面解释。

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

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

问题是,VS允许在设置文件中默认序列化int[]类型 – 它默认情况下不允许您选择它。 因此,创建一个具有所需名称的设置(例如SomeTestSetting)并使其成为任何类型(例如默认情况下为string )。 保存更改。

现在转到项目文件夹并使用文本编辑器打开“Properties \ Settings.settings”文件(例如,记事本)或者您可以通过右键单击解决方案资源管理器中的“ – >属性 – > Settings.settings”在VS中打开它“,选择”打开方式…“,然后选择”XML编辑器“或”源代码(文本)编辑器“。 在打开的xml设置中找到您的设置(它将如下所示):

    

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

    

现在保存更改并重新打开项目设置 – 瞧! – 我们使用类型System.Int32[]设置SomeTestSetting,可以通过VS Settings Designer(值也可以)以及代码访问和编辑。

储藏:

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

重新创建:

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

编辑:阿贝尔的建议!

还有另一种方法可以实现这个结果,使用起来更干净但需要更多代码。 我实现了自定义类型和类型转换器,可以使用以下代码:

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

要实现此目的,您需要一个带有类型转换器的类型,允许转换为字符串和从字符串转换 您可以通过使用TypeConverterAttribute修改类型来完成此操作:

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

然后将此类型转换器实现为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 arr = new List(); if (data != null) { foreach (string txt in data.ToString().Split(',')) arr.Add(int.Parse(txt)); } return new MyNumberArray(arr); } } 

通过在MyNumberArray类上提供一些便捷方法,我们可以安全地从List中分配,完整的类看起来像:

 [TypeConverter(typeof(MyNumberArrayConverter))] public class MyNumberArray : IEnumerable { List _values; public MyNumberArray() { _values = new List(); } public MyNumberArray(IEnumerable values) { _values = new List(values); } public static implicit operator List(MyNumberArray arr) { return new List(arr._values); } public static implicit operator MyNumberArray(List values) { return new MyNumberArray(values); } public IEnumerator GetEnumerator() { return _values.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)_values).GetEnumerator(); } } 

最后,要在设置中使用它,请将上述类添加到程序集并进行编译。 在Settings.settings编辑器中,只需单击“浏览”选项并选择MyNumberArray类即可。

这又是更多的代码; 但是,它可以应用于比简单数组更复杂的数据类型。

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

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

一个简单的解决方案是在属性中将设置的默认值设置为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; } } } 

它感觉有点hacky,但它干净并且按照需要工作,因为在调用构造函数之前,属性被初始化为它们的最后(或默认)设置。

使用System.Object

例:

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

提取:

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

我认为您对序列化设置是正确的。 有关示例,请参阅我对此问题的回答:

在两个应用程序之间共享配置的技术?

你将拥有一个数组属性,如下所示:

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

创建一些在字符串中转换int数组的函数,但在每个函数之间放置一个像“”(空格)的字符。

因此,如果数组为{1,34,546,56},则字符串为“1 34 645 56”