4

I was wondering if there is a recommended approach to defining a property of a plain object that is used for data transfer, for example via a REST-API which is a list of other objects. Which C# type should one prefer for defining those?

  • List<T> maybe? It's short, everybody knows it, and we don't have to cast or transform it into a list to do sorting, modifying etc.
  • ICollection<T> maybe? It's an interface that has a clear meaning and supports other types of enumerations, which avoids transforming those into a list on the sender side.
  • IEnumerable<T> maybe? It's even stricter than ICollection.
  • Arrays, T[] maybe? Even shorter, but you need to transform those from lists and vice versa. Not so nice for working with out-of-the-box (well, REST-response).
  • 2
    Use the "simplest" (most abstract) definition that will serve the needs of the clients. General rule is usually this: If you don't NEED it, don't use it. – Caleb Sep 7 '17 at 5:13
  • 3
    According to Microsoft's own guidelines "✓ DO use the least-specialized type possible as a parameter type. Most members taking collections as parameters use the IEnumerable<T> interface. " - docs.microsoft.com/en-us/dotnet/standard/design-guidelines/… - In a RESTful API, this advice makes a lot of sense because the main purpose of a DTO is for serialisation (presumably to JSON, and most likely using the Newtonsoft.Json serialiser) – Ben Cottrell Sep 7 '17 at 5:35
  • You can review the comparison of the interface contract for these collection types. To summarize: IEnumerable doesn't have a Count property. This means if you need to know its count, the only way is to iterate through it. This typically means you have to copy its entire content into a List, which in turn means: while accepting IEnumerable is good, promising (providing) only an IEnumerable is bad. ICollection doesn't have an indexer (the [int index] operator). – rwong Sep 8 '17 at 9:07
8

Generally speaking DTOs (Data Transfer Objects) need to be serialized in order to be transferred, for example to JSON.

Types like IList and IEnumerable can easily be serialized but are not so easy to deserialize because the serializer has to pick a concrete type.

In my experience the best balance between convenience, functionality and efficiency is List<T> but your specific use case may justify a different choice.

Note that because DTOs typically reference concrete types, they can not be tested and therefore should not contain any methods.

  • 1
    If you are serializing/deserializing the DTO it makes a difference, The older(legacy) XMLSerializer requires concrete types. Even NewtonSoft requires a specific constructor to support deserialization of interfaces...stackoverflow.com/questions/5780888/… – Jon Raynor Sep 7 '17 at 14:54
  • If you are using DTOs to transfer data to/from a database, the ORM you are using might support interfaces and serializability might not be an issue, but sooner or later it is likely that serialization will become an issue so it makes sense to use concrete types from the outset. – bikeman868 Sep 8 '17 at 0:51
  • I agree with this answer - and I would say that if you need the "lazy" aspect of IEnumerables/enumeration, you should consider using a yield return strategy instead. – contactmatt Oct 29 '18 at 20:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.