0

I've a requirement for a custom list.

I've defined its interface like this...

public interface IMyList: IList<IMyListItem>
{
    // Stuff
}

and the concrete class is defined like this ...

public class MyList : List<IMyListItem>, IMyList
{

}

All is good.

Until, I try and deserialize something into an instance of MyList. When I do that using something like this ...

var result = JsonConvert.DeserializeObject<MyList>(someString)

JSon.NET complains with this message...

Message=Could not create an instance of type IMyListItem. Type is an interface or abstract class and cannot be instantiated.

I get what the message is telling me, but I can't work out what do do with my class and interface definitions.

I could change the definition of MyList to public class MyList : List<MyListItem> but then the interface is dependent on a concrete class and, more importantly for me, it creates a circular reference (my Models and the interfaces that define them are in separate assemblies).

Am I just doing it wrong? It it not reasonable to have the Interfaces and Class implementations in different assemblies? Is there a technique/pattern that I should be using for this that I'm not?

Stuart Hemming
  • 1,553
  • 2
  • 21
  • 44
  • 2
    Possible duplicate of [Json.NET - Type is an interface or abstract class and cannot be instantiated](http://stackoverflow.com/questions/24644464/json-net-type-is-an-interface-or-abstract-class-and-cannot-be-instantiated) – Jan Köhler Dec 17 '15 at 13:01
  • 1
    Have a look at this question: http://stackoverflow.com/questions/5780888/casting-interfaces-for-deserialization-in-json-net – Alex Dec 17 '15 at 13:01
  • What does your `MyList` give you that a simple `List` wouldn't? You might want to consider composition instead of inheritance here. – juharr Dec 17 '15 at 13:01
  • _sigh_. Moments after posting the Q it came to me. Simply call `JsonConvert.DeserializeObject>(someString)` instead. – Stuart Hemming Dec 17 '15 at 13:03
  • @juharr. I have a number of custom set operations in the MyList – Stuart Hemming Dec 17 '15 at 13:10

2 Answers2

1

How about using a generic type with an inheritance restriction?

public interface IMyList<T>: IList<T> where T : IMyListItem
{
    // Stuff
}

public class MyList : List<MyListItem>, IMyList<MyListItem>
{

}

...and using it like so:

var result = JsonConvert.DeserializeObject<MyList>(someString)

Your interface will then not be based on a concrete class, but on an inheritance restriction to another interface instead. Your MyList class on the other hand wont have to be a list of interfaces (IMyListItem) but instead a list of MyListItems instead.

Shazi
  • 1,490
  • 1
  • 10
  • 22
0

A few people have pointed me to other answers, all of which I will check out but, in this specific instance I realised I could just change the call to deserialize the object from ...

var result = JsonConvert.DeserializeObject<MyList>(someString)

to

var result = new MyList();
result.AddRange(JsonConvert.DeserializeObject<List<MyListEntry>>(someString));
Stuart Hemming
  • 1,553
  • 2
  • 21
  • 44