2010-09-09 7 views
1

Я создаю объект Settings в своем приложении, который используется для хранения пользовательских настроек и много чего. Я планирую использовать различные типы данных для моих полей настроек (ints, string, enums, что-то Serializable, действительно).«Сохранить» параметр типа для последующего использования в C#?

Я также хотел бы, если возможно, безопасный тип установки любых параметров. Предлагаемый мною метод будет делать что-то вроде этого:

Tuple<string, Type> SettingName = new Tuple<string, Type>("NumberOfFoos", 
                  typeof(**TYPE**)); 
public void Set(Tuple<string, Type> key, **TYPE** value) { /* Stuff */ } 

Кортеж будет эффективно быть «установка», что пользователь должен нажать значение, и будет состоять из ключевых для этой установки, а также тип это настройка. Мне интересно, есть ли способ заставить компилятор обеспечить, чтобы в методе Set() тип value был того же типа, что и объект типа, сохраненный в кортеже, переданном Set()? Возможно ли, что я предложил? Благодаря!

EDIT: Я подумал о некоторых вещах, которые я должен уточнить.

1) Предполагается, что это статический класс, поэтому я не буду сериализовать весь класс, только его члены. Поэтому мне бы очень хотелось иметь дело с сериализацией для каждого поля. Я планировал сохранить все значения настроек в Dictionary<string, **TYPE**> и сериализовать это.

2) Определения Tuple должны быть постоянными и статическими. Я действительно рассматриваю их как нечто вроде типа типа typedef (я действительно должен создать собственную структуру SetKey), которую пользователь переходит к Set, чтобы указать, какое поле они меняются. Параметр Type предназначен для принудительного применения параметра value указанного типа.

ответ

2

Что-то вроде

public void Set<T>(Tuple<string,T> key, T value) { /* stuff */ } 

может сделать это

+0

На самом деле, это закончилось очень хорошо, спасибо! –

0

Ну, если вы сделали что-то вроде Set<T>(Tuple<string, T>, T value), вы получите то, что вы после того, как для установки. И я думаю, что компилятор мог вывести T в Set<T>() при использовании, поэтому вам придется написать его.

Но ваш Get<T>(), вам нужно будет указать тип, который вы ожидали получить.

2

Это лучше, чтобы избавиться от кортежа, и использовать общий метод:

public void Set<T>(string key, T value); 

Таким образом, вы можете указать тип во время компиляции

Set<string>("MyStringKey", "foo"); 
Set<int>("MyIntKey", 1); 

или компилятор может сделать вывод, это для вас:

Set("MyStringKey", "foo"); 
Set("MyIntKey", 1); 

и Set, вы можете использовать typeof(T) для ге т в Type объекта, который вы бы прошли в.

+0

Дело в том, что я хотел бы обеспечить, чтобы параметр значения имел тип, указанный мной в кортеже. –

+0

, но вы не _need_ кортеж, компилятор может автоматически выработать тип без него, в зависимости от типа параметра 'value' – thecoop

0
public class Foo 
{ 
    Tuple<string, Type> SettingName = new Tuple<string, Type>("NumberOfFoos", 
                  typeof(**TYPE**)); 
    public void Set(Tuple<string, Type> key, object value) 
    { 
    if(value.GetType() != SettingsName.Value) 
     throw new ArgumentException("value"); 
    } 
} 

Вы бы лучше использовать дженерики, как и в других ответах, хотя.

2

Почему бы просто не добавить строго типизированные свойства к вашему объекту настроек? например public int NumberOfFoos {get {} set {...}}, а в приемнике и сеттере вызывают общий код сериализации и десериализации.

Если вы сделаете это, объект настроек не будет раскрывать, как он работает внутри, и у вас есть полная поддержка intellisense.

+0

Ну, я также хочу избежать использования частного поля numberOfFoos и отдельного свойства NumberOfFoos, для каждого из моих 60 или около того полей настройки. Я планировал использовать словарь для хранения всех настроек на основе ключа. Я должен был бы использовать при извлечении значений, но именно поэтому я хотел использовать такие типы. –

+0

Вы можете сделать все автоматические свойства, например. 'public int NumberOfFoos {get; set;} 'add для сериализации вы можете добавить' [DataContract] 'к классу и атрибуту' [DataMember] 'для каждого свойства, что делает его однострочным, чтобы сериализовать весь класс настроек в XML или JSON и т. д. Это быть намного чище в целом. –

0

Я не думаю, что вам нужно иметь дело с Type s на всех. Будет ли что-то вроде этого достаточно хорошим?

class Settings { 
    public static int Foo { 
    get { return (int)_map["Foo"]; } 
    set { _map["Foo"] = value; } 
    } 
    public static string Bar { 
    get { return (string)_map["Foo"]; } 
    set { _map["Foo"] = value; } 
    } 
    // ... 
    private static Dictionary<string, object> _map = 
    new Dictionary<string, object>(); 
} 

После этого сериализуйте словарь. Для создания этого класса вы даже можете использовать code-generation.

Смежные вопросы