Тип — это интерфейс или абстрактный класс, экземпляр которого не может быть создан.C#

Место общения программистов C#
Anonymous
Тип — это интерфейс или абстрактный класс, экземпляр которого не может быть создан.

Сообщение Anonymous »

Я начну с того, что знаю, в чем проблема, но не знаю, как ее решить. Я общаюсь с уровнем данных .NET SOA, который возвращает данные в формате JSON. Один из таких методов возвращает объект, содержащий несколько коллекций. Объект в основном выглядит так:

Код: Выделить всё

{
"Name":"foo",
"widgetCollection":[{"name","foo"}, {"name","foo"},],
"cogCollection": [{"name","foo"}, {"childCogs",},],
}
Мой класс, представляющий этот объект, выглядит следующим образом:

Код: Выделить всё

public class SuperWidget : IWidget
{
public string Name { get; set; }

public ICollection WidgetCollection { get; set; }
public ICollection CogCollection { get; set; }

public SuperWidget()
{
}

[JsonConstructor]
public SuperWidget(IEnumerable widgets, IEnumerable cogs)
{
WidgetCollection = new Collection();
CogCollection = new Collection();

foreach (var w in widgets)
{
WidgetCollection.Add(w);
}
foreach (var c in cogs)
{
CogCollection.Add(c);
}
}
}
Этот конструктор работал нормально, пока cogCollection не добавил дочернюю коллекцию, и теперь я получаю вышеуказанную ошибку. Конкретный класс винтика выглядит так:

Код: Выделить всё

[Serializable]
public class Cog : ICog
{
public string name { get; set; }

public ICollection childCogs { get; set; }
}
Я не хочу менять коллекцию на конкретный тип, потому что я использую IoC. Поскольку я использую IoC, мне бы очень хотелось избавиться от необходимости иметь JsonConstructors, принимающие конкретные параметры, но я не нашел способа сделать это. Будем очень признательны за любые советы!

Обновление:

Предположение Ювала Ицчакова о том, что этот вопрос, вероятно, является дубликатом, в некоторой степени верно (кажется). В указанном сообщении один из ответов на странице предлагает то же решение, что и здесь. Я не заметил этого ответа, поскольку вопрос ОП отличался от того, который был у меня здесь. Моя ошибка.

-------мое решение--------

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

Код: Выделить всё

 return objectType == typeof(ICog);
Следуя этому шаблону, вам понадобится JsonConverter для каждого абстрактного типа, который вы получаете по сети. В моей ситуации это далеко не идеально, поэтому я создал универсальный JsonConverter как таковой:

Код: Выделить всё

public class GenericJsonConverter: JsonConverter, IBaseJsonConverter
{
private readonly IUnityContainer Container;
public GenericJsonConverter(IUnityContainer container)
{
Container = container;
}

public override bool CanConvert(Type objectType)
{
return objectType == typeof(T);
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var target = serializer.Deserialize(reader);
var result = Container.Resolve();
serializer.Populate(target.CreateReader(), result);
return result;
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
}
Затем, прежде чем десериализовать данные, я делаю что-то вроде этого:

Код: Выделить всё

 var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All };
settings.Converters.Add((JsonConverter)Container.Resolve());
Совет: если вы используете Resharper, (JsonConverter) в этом сценарии выдаст вам предупреждение о подозрительном приведении.

Надеюсь, кто-нибудь еще найдет это полезным в будущем!

Вернуться в «C#»