С# Общий способ хранения неизвестных свойств в списке

Я хотел бы хранить LicenseInformations для нескольких доменов в своем приложении.

Структура выглядит следующим образом:

   public class LicenseData
    {
        // properties...
        public List<LicenseDomain> Domains { get; set; }
        // other properties...
    }

    public class LicenseDomain
    {
        // properties...
        public object LicenseConfig { get; set; }
    }

У нас есть несколько доменов с разными свойствами, но лицензия может содержать несколько конфигураций.

Например:

{
   "MaxValidUsers": 5
}
{
   "Property": "xy"
   "SubProperty": { "Foo" : "Bar" 
   }
}

Генерация в любом случае не проблема. Но если я восстановлю информацию из моего подписанного файла json, я десериализую объект.

Какой шаблон/возможность у меня есть для работы с интерфейсами/рефератами/что я могу (RE) хранить здесь общую информацию.

Прямо сейчас я взламываю с помощью:

JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(domain.LicenseConfig))

Но я не могу согласиться с собой.


person Andréw    schedule 14.09.2020    source источник
comment
рассмотрите возможность использования базового класса...   -  person Daniel A. White    schedule 14.09.2020
comment
с каким содержанием? объект останется, я думаю..   -  person Andréw    schedule 14.09.2020
comment
как насчет stackoverflow.com/a/4416536/2133965?   -  person VietDD    schedule 14.09.2020


Ответы (1)


Итак, основываясь на фрагментах контекста, которые я могу получить, я бы рекомендовал хранить ваши LicenseConfig в виде строки JSON, что дало бы вам возможность сделать что-то вроде этого:

public class LicenseDomain
{
    // properties...

    // Depending on how this is loaded,
    // this property (or at least its setter) could be made private/protected/internal
    public string LicenseConfigJson { get; set; }

    public T LicenseConfig<T>() where T : BaseLicenseConfig
    {
        if (string.IsNullOrWhiteSpace(LicenseConfigJson))
        {
            return null;
        }
        return JsonConvert.DeserializeObject<T>(LicenseConfigJson);
    }
    public void SaveLicenseConfig<T>(T config) where T : BaseLicenseConfig
    {
        if (config == null)
        {
            LicenseConfigJson = null; 
        }
        else
        {
            LicenseConfigJson = JsonConvert.SerializeObject(config);
        }
    }


}

Или, если каждый LicenseDomain может иметь только один тип LicenseConfig, вы можете сделать его общим параметром для класса:

public class LicenseData
{
    // properties...
    public List<LicenseDomain<BaseLicenseConfig>> Domains { get; set; }
    // other properties...
}

public class LicenseDomain<T> where T : BaseLicenseConfig
{
    // properties...

    // Depending on where this value comes from, you could do this a variety of ways, 
    //but this is just one
    public string LicenseConfigJson { get; set; }
    public T LicenseConfig
    {
        get
        {
            if (string.IsNullOrWhiteSpace(LicenseConfigJson))
            {
                return null;
            }
            return JsonConvert.DeserializeObject<T>(LicenseConfigJson);
        }
        set
        {
            if (value == null)
            {
                LicenseConfigJson = null;
            }
            else
            {
                LicenseConfigJson = JsonConvert.SerializeObject(value);
            }
        }
    }
}

public abstract class BaseLicenseConfig
{
    
}

public class LicConfig1 : BaseLicenseConfig
{
    public int MaxValidUsers { get; set;}
}

public class LicConfig2 : BaseLicenseConfig
{
    public string Property {get;set;}
    public SubProp SubProperty {get;set;}
}

public class SubProp
{
    public string Foo {get;set;}
}

В обоих случаях класс BaseLicenseConfig строго следит за тем, чтобы все в списке доменов могло исходить из какого-либо базового класса. Если это не важно, вам не нужен базовый класс, и вы можете удалить where T : BaseLicenseConfig из класса LicenseDomain.

person s0n1c    schedule 15.09.2020