Преобразование переменной из типа, хранящегося в другой переменной C#

#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 вы можете подумать о том, чтобы инкапсулировать это в пользовательский конвертер.