2015-08-03 1 views
0

У меня есть следующие четыре строки; две пары, каждая из которых содержит строку, представляющую значение, и тип данных.Как вы можете создать экземпляр экземпляра типа, уже установленного для определенного значения, если у вас есть только строковое представление типа и значения?

string stringValueOfA = "Hello World!"; 
string stringTypeOfA = "System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; 

string stringValueOfB = "44"; 
string stringTypeOfB = "System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; 

Я знаю, что я могу получить типы каждого, как так ...

var typeOfA = Type.GetType(stringTypeOfA); 
var typeOfB = Type.GetType(stringTypeOfB); 

... и я могу активировать новые экземпляры указанных типов, как это ...

var a = Activator.CreateInstance(typeOfA); 
var b = Activator.CreateInstance(typeOfB); 

... но я не уверен, как создавать экземпляры, которые установлены в значение, закодированное в его строковых представлениях stringValueOfA и stringValueOfB.

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

ответ

1

Многие BCL типов, в том числе и StringInt32, ассоциировали преобразователи типа, которые могут быть использованы для преобразования строк в экземпляры этих типов и наоборот. Если вы работаете с одним из этих типов, то вы можете разобрать строку, как это:

public static object ConvertFromString(string typeName, string value) 
{ 
    Type type = Type.GetType(typeName, true); 
    TypeConverter converter = TypeDescriptor.GetConverter(type); 
    return converter.ConvertFromString(value); 
} 

Пример использования:

object valueOfA = ConvertFromString(stringTypeOfA, stringValueOfA); // returns "Hello World!" 
object valueOfB = ConvertFromString(stringTypeOfB, stringValueOfB); // returns 44 as an int 

Примечание: Поскольку фактический тип не известен во время компиляции , бокс типов значений неизбежен.

+0

Бинго! Да, из того, что я понимаю, это то, что делает Parse (или, по крайней мере, похоже на то, что он делает) под капотом. Благодаря! – MarqueIV

+1

На самом деле, во многих случаях преобразователь типов просто вызывает статический метод Parse связанного типа. Хорошая вещь о преобразователях типов заключается в том, что они дают вам стандартизованный, тип агностик, объектно-ориентированный способ выполнения преобразования строк. –

1

Activator.CreateInstance, Создает экземпляр типа, указанного указанным параметром общего типа, используя конструктор без параметров. Вы должны установить значение после создания экземпляра.

Activator.CreateInstance(typeOfA); 

CreateInstance() общий метод используется компиляторами для реализации экземпляра типов, определенных параметров типа. Подробнее here.

+0

Да, я знаю об активаторе. Это легко. Вы пропустили вторую половину этого предложения. «... создайте экземпляр этого типа *, инициализированный в разобранном значении строки *« Опять же, да, я могу активировать новый тип, как его инициализировать со значением, содержащимся в строке, когда я не иметь доступ к методу анализа? – MarqueIV

+0

@MarqueIV: Вы не можете передать значение. Он просто создает экземпляр с использованием пустого конструктора, а затем вы должны устанавливать значения конкретно. – CharithJ

+1

Это не имеет смысла! Как вы можете установить значение int? Значение int * - это значение! Активация нового int даст вам int с нулевым значением, но если 'stringValueOfA' равно« 3 », тогда мне нужен int of 3. Я не могу назначить 3 нулю. Конечно, я мог бы сохранить этот ноль в переменной, но тогда мне нужно было бы назначить «3» этой переменной, которая заменила бы тот, который вы создали с помощью Activator, и b) выходит на полный круг, поскольку он все еще не работает «Получи мне значение 3 из строки! Похоже, что получение TypeConverter для типа является ответом. Активатор ничего не дает. – MarqueIV