#c# #asp.net #dynamic #type-conversion
#c# #asp.net #динамический #преобразование типа
Вопрос:
Мне нужно преобразовать динамическую переменную из типа, хранящегося в другой переменной.
Например:
dynamic dynamicVar = 3;
string type = "double";
var valueConverted = (type) dynamicVar;
Я знаю, что это не работает, но есть ли способ сделать что-то подобное?
Я получаю такой JSON:
[
{
"name": "Parameter1",
"description": "Description",
"value": "Value",
"type": "string"
},
{
"name": "Parameter1",
"description": "Description",
"value": false,
"type": "boolean"
},
{
"name": "Parameter3",
"description": "Description",
"value": 3,
"type": "double"
}
]
Мне нужно преобразовать этот json в подобный объект:
public class Parameters
{
public string Parameter1 { get; set; }
public bool Parameter2 { get; set; }
public double? Parameter3 { get; set; }
}
Когда я попытался сохранить Параметр3, я получил сообщение об ошибке:
невозможно преобразовать Int в Double
Комментарии:
1. C # является статически типизированным. Я не думаю, что что-то подобное возможно в c #. Но вы могли бы выполнить оператор switch case, который обеспечивает это.
2. Какая реальная польза от чего-то подобного? Для меня это похоже на проблему xy , TBH. Не могли бы вы предоставить больше информации о фактическом использовании / коде?
3. Я создаю список параметров для отображения во внешнем интерфейсе, и когда я получил этот список обратно, я должен сохранить введенные значения. Я буду использовать этот код в классе Mapper, преобразуя из Json в объект.
4. Почему бы вам просто не использовать существующий сериализатор json, который отображает json в классы моделей?
5. @FrederikPietzko Да, на самом деле я использовал случай переключения, но я искал лучший подход.
Ответ №1:
Если я вас правильно понимаю, что вы можете сделать, это сначала сгенерировать схему JSON из вашего JSON:
var schema = JsonSchema.FromSampleJson("...");
Затем вы можете использовать NJsonSchema для создания из нее класса. HTH.
Ответ №2:
Попробуйте это:
dynamic dynamicVar = 3;
var valueConverted = default(dynamicVar.GetType()); //This will set the right type
valueConverted = dynamicVar;
Ответ №3:
Вы можете использовать некоторую магию отражения, чтобы установить эти поля. Что-то вроде этого (я использую Newtonsoft Json.NET как библиотека json) :
class Parameters
{
public string Parameter1 { get; set; }
public bool Parameter2 { get; set; }
public double Parameter3 { get; set; }
public override string ToString()
{
return $"{nameof(Parameter1)}: {Parameter1}, {nameof(Parameter2)}: {Parameter2}, {nameof(Parameter3)}: {Parameter3}";
}
}
var json = @" [
{
""name"": ""Parameter1"",
""description"": ""Description"",
""value"": ""Value"",
""type"": ""string""
},
{
""name"": ""Parameter2"",
""description"": ""Description"",
""value"": false,
""type"": ""boolean""
},
{
""name"": ""Parameter3"",
""description"": ""Description"",
""value"": 3,
""type"": ""double""
}
]";
var typeMap = new Dictionary<string, Type>
{
{"double", typeof(double)},
{"boolean", typeof(bool)},
{"string", typeof(string)},
};
var jArray = JArray.Parse(json);
var result = new Parameters();
var methodInfo = typeof(Newtonsoft.Json.Linq.Extensions).GetMethod("Value", 1, new []{typeof(IEnumerable<JToken>)});
foreach (var jObj in jArray)
{
var method = methodInfo.MakeGenericMethod(typeMap[jObj["type"].Value<string>()]);
var value = method.Invoke(null, new[] {jObj["value"]});
typeof(Parameters).GetProperty(jObj["name"].Value<string>())
.SetValue(result, value);
}
Console.WriteLine(result); // prints "Parameter1: Value, Parameter2: False, Parameter3: 3"
Этот код можно значительно улучшить с помощью различных видов обработки исключений, кэширования и т. Д., Но Он должен дать вам общее представление о том, как вы можете подойти к своей задаче (если я правильно понял).
Также, если вы будете придерживаться Json.NET lib вы можете подумать о том, чтобы инкапсулировать это в пользовательский конвертер.