«Сохранить» параметр типа для последующего использования в C #? - PullRequest
1 голос
/ 09 сентября 2010

Я создаю объект «Настройки» в своем приложении, который используется для хранения пользовательских настроек и прочего. Я планирую использовать различные типы данных для своих полей настройки (целые числа, строки, перечисления, все, что угодно Serializable, правда).

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

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

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

РЕДАКТИРОВАТЬ: Я подумал о некоторых вещах, которые я должен уточнить.

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

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

Ответы [ 6 ]

2 голосов
/ 09 сентября 2010

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

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

2 голосов
/ 09 сентября 2010

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

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 объект, который вы бы передали.

2 голосов
/ 09 сентября 2010

Что-то вроде

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

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

0 голосов
/ 09 сентября 2010

Я не думаю, что вам вообще нужно иметь дело с 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>();
}

Затем вы бы сериализовали словарь. Вы могли бы даже использовать генерацию кода для создания этого класса.

0 голосов
/ 09 сентября 2010
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");
  }
}

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

0 голосов
/ 09 сентября 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...