C #: как использовать универсальный метод с переменной "out" - PullRequest
8 голосов
/ 15 ноября 2009

Я хочу создать простую универсальную функцию

void Assign<T>(out T result) 
{
  Type type = typeof(T);
  if (type.Name == "String")
  {
     // result = "hello";
  }
  else if (type.Name == "Int32")
  {
     // result = 100;
  } 
  else result = default(T);
}

Использование:

int value;
string text;

Assign(value); // <<< should set value to 100
Assign(text); // <<< should set text to "hello"

Мой вопрос: как вы программируете код для установки этих значений, т.е. недостающие коды в разделе комментариев.

Спасибо за любую помощь.

Ответы [ 4 ]

16 голосов
/ 15 ноября 2009

Похоже, что в этом случае вы пытаетесь избежать бокса? Трудно сказать без дополнительной информации, но для этого конкретного примера было бы гораздо проще и, вероятно, менее подвержено ошибкам просто использовать перегрузку методов:

void Assign(out string value)
{
   //...
}

void Assign(out int value)
{
   //...
}

В целях изучения, в частности, что является неправильным , вам необходимо привести значение к объекту перед преобразованием его в универсальный тип:

(T)(object)"hello world!";

Какой IMO довольно неприятный и должен быть последним средством - конечно, не делает ваш код чище.

Всякий раз, когда вы выполняете проверку типов общих параметров, это хороший признак того, что обобщенные значения не являются правильным решением вашей проблемы. Выполнение общих проверок типов параметров делает ваш код более сложным, а не проще. Это делает один метод ответственным за различное поведение, основанное на типе, вместо серии отдельных методов, которые легко изменить без случайного влияния на другие. См. Принцип единой ответственности .

3 голосов
/ 15 ноября 2009

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

Код ниже работает, но, как я уже сказал, написание кода таким способом - плохая идея.

    void Assign<T>(out T result) 
    { 
        Type type = typeof(T); 
        if (type.Name == "String") 
        { result = (T) ((object)"hello"); } 
        else if (type.Name == "Int32") 
        { result = (T) ((object)100); } 
        else result = default(T); 
    }

И использование:

        int value;
        string text;

        Assign(out value);
        Assign(out text);
1 голос
/ 07 сентября 2011
public T GetObject<T>(string val)
{
    T _object = default(T);
    _object = (T)Convert.ChangeType(val, typeof(T));
    return _object;
}
0 голосов
/ 15 ноября 2009

Вот один из способов:

static void Assign<T>(out T result) { 
    Type type = typeof(T);
    if (type.Name == "String") {
        result = (T)Convert.ChangeType("hello", typeof(T));
    }
    else if (type.Name == "Int32") {
        result = (T)Convert.ChangeType(100, typeof(T));
    }
    else {
        result = default(T);
    }
}

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

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