programing

애플리케이션 설정에 int [] 배열을 저장하는 방법

nasanasas 2020. 9. 7. 08:13
반응형

애플리케이션 설정에 int [] 배열을 저장하는 방법


저는 C # express 2008을 사용하여 간단한 Windows Forms 응용 프로그램을 만들고 있습니다. 저는 경험이 많은 C ++ 개발자이지만 C # 및 .NET에 익숙하지 않습니다.

현재 설정 디자이너와 다음과 같은 코드를 사용하여 간단한 응용 프로그램 설정 중 일부를 저장하고 있습니다.

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

이제 설정으로 int 배열 ( int[]) 또는 아마도 ints 목록 ( ) 중 하나를 저장하고 싶습니다 List< int >. 그러나 이것을 수행하는 방법을 알 수 없습니다. 문서, stackoverflow 및 google을 검색했지만이를 수행하는 방법에 대한 적절한 설명을 찾을 수 없습니다.

내가 찾은 드문 예를 기반으로 한 내 직감은 배열 또는 목록을 래핑하는 직렬화 가능한 클래스를 만들어야한다는 것입니다. 그러면 설정 디자이너에서 해당 유형을 사용할 수 있습니다. 그러나 정확히 어떻게해야하는지 잘 모르겠습니다.


또 다른 솔루션도 있습니다. 설정 파일을 약간 수동으로 편집해야하지만 나중에 VS 환경과 코드에서 잘 작동합니다. 추가 기능이나 래퍼가 필요하지 않습니다.

문제는 VS int[]가 설정 파일에서 기본적으로 유형 을 직렬화 할 수 있다는 것입니다 . 기본적으로 선택할 수는 없습니다. 따라서 원하는 이름 (예 : SomeTestSetting)으로 설정을 만들고 모든 유형 (예 string: 기본적으로)으로 만듭니다. 변경 사항을 저장하십시오.

이제 프로젝트 폴더로 이동하여 텍스트 편집기 (예 : 메모장)로 "Properties \ Settings.settings"파일을 열거 나 솔루션 탐색기에서 "-> 속성-> Settings.settings를 마우스 오른쪽 단추로 클릭하여 VS에서 열 수 있습니다. "에서"연결 프로그램 ... "을 선택한 다음"XML 편집기 "또는"소스 코드 (텍스트) 편집기 "를 선택합니다. 열린 xml 설정에서 설정을 찾습니다 (다음과 같이 표시됨).

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

"Type"매개 변수를에서 System.String변경하십시오 System.Int32[]. 이제이 섹션은 다음과 같습니다.

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

이제 변경 사항을 저장하고 프로젝트 설정을 다시 엽니 다-voilà! - System.Int32[]코드에서뿐만 아니라 VS 설정 디자이너 (값도)를 통해 액세스하고 편집 할 수있는 유형으로 SomeTestSetting 설정 이 있습니다.


저장하려면 :

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

다시 만들려면 :

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

편집 : Abel 제안!


이 결과를 얻을 수있는 또 다른 방법은 사용이 훨씬 깨끗하지만 더 많은 코드가 필요합니다. 사용자 지정 형식 및 형식 변환기를 구현하면 다음 코드가 가능합니다.

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 ...

그런 다음이 형식 변환기를 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에 안전하게 할당 할 수 있으며 전체 클래스는 다음과 같습니다.

[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 클래스를 선택하기 만하면됩니다.

Again this is a lot more code; however, it can be applied to much more complicated types of data than a simple array.


Specify the setting as a System.Collections.ArrayList and then:

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

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

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:

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.


Used System.Object.

Example:

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

Extract:

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

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

Make some functions that convert a int array in a string, but between each put a character like " " (space).

So if the array is { 1,34,546,56 } the string would be "1 34 645 56"

참고URL : https://stackoverflow.com/questions/1766610/how-to-store-int-array-in-application-settings

반응형