Десериализация файла JSON в статический класс в C # - PullRequest
0 голосов
/ 15 мая 2018

У меня есть статический класс со статическими полями и json.

Я могу десериализовать json в динамический объект, поэтому у меня есть все поля, и они точно соответствуют статическим полям в классе.

Как я могу использовать отражение, чтобы перечислить поля и скопировать значения из динамического класса в поля статического класса?

Я не могу изменить архитектуру, сделать ее одиночной и т. Д .; это общий код, и класс будет оставаться статическим, поскольку это глобально используемый объект настроек, используемый общей библиотекой.

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


Добавление более подробной информации, но на самом деле не так много:

У меня есть статический класс:

static class A
{
    static int I;
    static string S;
}

и JSON, точно совпадающий с полями:

{
    "I" : 3,
    "S" : "hello"
}

var Data = JsonConvert.Deserialize<dynamic>(...);

Я хотел бы инициализировать статические поля класса A значениями, десериализованными из json, в динамический объект.


Другое редактирование:

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

вот что я придумал:

foreach (var Destination in typeof(Settings).GetProperties())
{
    var Name = Destination.Name;
    var T = Destination.PropertyType;
    var Value = JsonConvert.DeserializeObject("\"" + JT[Name] + "\"", T);
    Destination.SetValue(null, Value);
}

1 Ответ

0 голосов
/ 15 мая 2018

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

public static class A
{
    public static int I { get; set; }
    public static string S { get; set; }
}

public class B
{
    public int I { get; set; }
    public string S { get; set; }
}

Теперь мы можем сделать это:

public void MapToStaticClass(B source)
{
    var sourceProperties = source.GetType().GetProperties();

    //Key thing here is to specify we want the static properties only
    var destinationProperties = typeof(A)
        .GetProperties(BindingFlags.Public | BindingFlags.Static);

    foreach (var prop in sourceProperties)
    {
        //Find matching property by name
        var destinationProp = destinationProperties
            .Single(p => p.Name == prop.Name);

        //Set the static property value
        destinationProp.SetValue(null, prop.GetValue(source));
    }
}

Другой вариант - десериализация до JToken и использование в сочетании с отражением:

var source = JsonConvert.DeserializeObject<JToken>(json);

А потом:

public void MapJTokenToStaticClass(JToken source)
{
    var destinationProperties = typeof(A)
        .GetProperties(BindingFlags.Public | BindingFlags.Static);

    foreach (JProperty prop in source)
    {
        var destinationProp = destinationProperties
            .SingleOrDefault(p => p.Name.Equals(prop.Name, StringComparison.OrdinalIgnoreCase));
        var value = ((JValue)prop.Value).Value;

        //The ChangeType is required because JSON.Net will deserialise
        //numbers as long by default
        destinationProp.SetValue(null, Convert.ChangeType(value, destinationProp.PropertyType));
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...