C# 如何在应用程序设置中存储 int[] 数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1766610/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to store int[] array in application Settings
提问by sidewinderguy
I'm creating a simple windows Forms application using C# express 2008. I'm an experienced C++ developer, but I am pretty much brand new to C# and .NET.
我正在使用 C# express 2008 创建一个简单的 Windows 窗体应用程序。我是一名经验丰富的 C++ 开发人员,但我对 C# 和 .NET 几乎是全新的。
I'm currently storing some of my simple application settings using the settings designer and code like this:
我目前正在使用设置设计器和如下代码存储一些简单的应用程序设置:
// Store setting
Properties.Settings.Default.TargetLocation = txtLocation.Text;
...
// Restore setting
txtLocation.Text = Properties.Settings.Default.TargetLocation;
Now I'd like to store either an array of ints ( int[]
), or possibly a List of ints ( List< int >
), as a setting. However, I can't figure out how to do this. I've searched the documentation, stackoverflow, and google, and I cannot find a decent explanation of how to do this.
现在我想存储一个整数数组 ( int[]
),或者可能存储一个整数列表 ( List< int >
),作为设置。但是,我无法弄清楚如何做到这一点。我搜索了文档、stackoverflow 和 google,但找不到有关如何执行此操作的正确解释。
My hunch based on the sparse examples I've found is that I have to create a class that is serializable that wraps my array or List, and then I will be able to use that Type in the settings designer. However, I'm not sure exactly how to do this.
基于我发现的稀疏示例,我的预感是我必须创建一个可序列化的类来包装我的数组或列表,然后我将能够在设置设计器中使用该类型。但是,我不确定如何做到这一点。
采纳答案by Jen-Ari
There is also another solution - requires a bit of manual editing of the settings file, but afterwards works fine in VS environment and in the code. And requires no additional functions or wrappers.
还有另一种解决方案 - 需要对设置文件进行一些手动编辑,但之后在 VS 环境和代码中工作正常。并且不需要额外的功能或包装器。
The thing is, that VS allows to serialize int[]
type by default in the settings file - it just doesn't allow you to select it by default.
So, create a setting with desired name (e.g. SomeTestSetting) and make it of any type (e.g. string
by default).
Save the changes.
问题是,VS 允许int[]
在设置文件中默认序列化类型 - 它只是不允许您默认选择它。因此,创建一个具有所需名称的设置(例如 SomeTestSetting)并使其成为任何类型(例如string
默认)。保存更改。
Now go to your project folder and open the "Properties\Settings.settings" file with text editor (Notepad, for example) Or you can open it in VS by right-clicking in Solution Explorer on " -> Properties -> Settings.settings", select "Open With..." and then choose either "XML Editor" or "Source Code (Text) Editor". In the opened xml settings find your setting (it will look like this):
现在转到您的项目文件夹并使用文本编辑器(例如记事本)打开“Properties\Settings.settings”文件,或者您可以通过在“解决方案资源管理器”中右键单击“-> 属性-> Settings.settings”在 VS 中打开它”,选择“打开方式...”,然后选择“XML 编辑器”或“源代码(文本)编辑器”。在打开的 xml 设置中找到您的设置(它看起来像这样):
<Setting Name="SomeTestSetting" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
Change the "Type" param from System.String
to System.Int32[]
. Now this section will look like this:
将“类型”参数从 更改System.String
为System.Int32[]
。现在这部分看起来像这样:
<Setting Name="SomeTestSetting" Type="System.Int32[]" Scope="User">
<Value Profile="(Default)" />
</Setting>
Now save changes and re-open project settings - voilà! - We have the setting SomeTestSetting with type System.Int32[]
which can be accessed and edited through VS Settings Designer (values too), as well as in the code.
现在保存更改并重新打开项目设置 - 瞧!- 我们有设置 SomeTestSetting 的类型System.Int32[]
,可以通过 VS 设置设计器(也有值)以及在代码中访问和编辑。
回答by Mike Gleason jr Couturier
to store:
储藏:
string value = String.Join(",", intArray.Select(i => i.ToString()).ToArray());
string value = String.Join(",", intArray.Select(i => i.ToString()).ToArray());
to re-create:
重新创建:
int[] arr = value.Split(',').Select(s => Int32.Parse(s)).ToArray();
int[] arr = value.Split(',').Select(s => Int32.Parse(s)).ToArray();
Edit: Abel suggestion!
编辑:亚伯的建议!
回答by Philip Wallace
I think you are right about serializing your settings. See my answer to this question for a sample:
我认为您对序列化设置是正确的。请参阅我对这个问题的回答以获取示例:
Techniques for sharing a config between two apps?
You would have a property which is an array, like this:
您将拥有一个数组属性,如下所示:
/// <summary>
/// Gets or sets the height.
/// </summary>
/// <value>The height.</value>
[XmlAttribute]
public int [] Numbers { get; set; }
回答by Jo?o Angelo
Specify the setting as a System.Collections.ArrayList and then:
将设置指定为 System.Collections.ArrayList,然后:
Settings.Default.IntArray = new ArrayList(new int[] { 1, 2 });
int[] array = (int[])Settings.Default.IntArray.ToArray(typeof(int));
回答by csharptest.net
There is one other way to achieve this result that is a lot cleaner in usage but requires more code. My implementing a custom type and type converter the following code is possible:
还有另一种方法可以实现此结果,该方法在使用中更简洁,但需要更多代码。我实现了自定义类型和类型转换器,以下代码是可能的:
List<int> array = Settings.Default.Testing;
array.Add(new Random().Next(10000));
Settings.Default.Testing = array;
Settings.Default.Save();
To achieve this you need a type with a type converter that allows conversion to and from strings. You do this by decorating the type with the TypeConverterAttribute:
为了实现这一点,您需要一个带有类型转换器的类型,该类型允许与字符串进行转换。您可以通过使用 TypeConverterAttribute 装饰类型来实现此目的:
[TypeConverter(typeof(MyNumberArrayConverter))]
public class MyNumberArray ...
Then implementing this type converter as a derivation of TypeConverter:
然后实现这个类型转换器作为 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);
}
}
By providing some convenience methods on the MyNumberArray class we can then safely assign to and from List, the complete class would look something like:
通过在 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(); }
}
Lastly, to use this in the settings you add the above classes to an assembly and compile. In your Settings.settings editor you simply click the "Browse" option and select the MyNumberArray class and off you go.
最后,要在设置中使用它,请将上述类添加到程序集并编译。在您的 Settings.settings 编辑器中,您只需单击“浏览”选项并选择 MyNumberArray 类即可。
Again this is a lot more code; however, it can be applied to much more complicated types of data than a simple array.
同样,这是更多的代码;但是,它可以应用于比简单数组更复杂的数据类型。
回答by Russell Bearden
A simple solution is to set the default value of a setting to null in the property, but in the constructor check if the property is null and if so then set it to its actual default value. So if you wanted an array of ints:
一个简单的解决方案是在属性中将设置的默认值设置为 null,但在构造函数中检查该属性是否为 null,如果是,则将其设置为其实际的默认值。所以如果你想要一个整数数组:
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;
}
}
}
It feels kind of hacky, but its clean and works as desired since the properties are initialized to their last (or default) settings before the constructor is called.
感觉有点 hacky,但它很干净并且可以按预期工作,因为在调用构造函数之前属性被初始化为其最后(或默认)设置。
回答by Slavs
Used System.Object
.
用过System.Object
。
Example:
例子:
byte[] arBytes = new byte[] { 10, 20, 30 };
Properties.Settings.Default.KeyObject = arBytes;
Extract:
提炼:
arBytes = (byte[])Properties.Settings.Default.KeyObject;
回答by user1452079
Make some functions that convert a int array in a string, but between each put a character like " " (space).
制作一些将 int 数组转换为字符串的函数,但在每个函数之间放置一个像“”(空格)这样的字符。
So if the array is { 1,34,546,56 } the string would be "1 34 645 56"
所以如果数组是 { 1,34,546,56 } 字符串将是“1 34 645 56”