Last active
December 16, 2015 06:29
-
-
Save gmcelhanon/5391894 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This class will not be serialized by protobuf-net because of the use of IEnumerable<T>: | |
[Serializable, ProtoContract] | |
public class GoalPlanningModel : ResourceModelBase | |
{ | |
[ProtoMember(1)] | |
public IEnumerable<ProposedGoal> ProposedGoals { get; set; } | |
[ProtoMember(2)] | |
public IEnumerable<PublishedGoal> PublishedGoals { get; set; } | |
} | |
// In order to get protobuf-net to serialize it, I have to change the IEnumerabe<T> members to IList<T>. | |
[Serializable, ProtoContract] | |
public class GoalPlanningModel : ResourceModelBase | |
{ | |
[ProtoMember(1)] | |
public IList<ProposedGoal> ProposedGoals { get; set; } | |
[ProtoMember(2)] | |
public IList<PublishedGoal> PublishedGoals { get; set; } | |
} | |
// When protobuf-net deserializes the second model, it will create a backing List<T> and populate it | |
// with the data, correct? Why is this a safe assumption? How do you know that I wasn't expecting a | |
// different IList<T> implementation there? You create a List<T> because it's consistent with the | |
// semantics defined by IList<T>, and therefore seems like a reasonable thing to do, right? But | |
// there's no gurantee that my original object was of type List<T>, just that it implemented the | |
// IList<T> interface. I could have a custom implementation of IList<T>, but my deserialized object | |
// wouldn't have that - it would have a List<T>. | |
// Now consider a model with properties that are of type IEnumerable<T>. What do the semantics say | |
// about this model? They indicate that I can enumerate and query against the collection, but I | |
// cannot change the contents by adding or removing items. | |
// If you make the judgement that a List<T> is an acceptable replacement for a IList<T>, why can't it | |
// also be an acceptable replacement for an IEnumerable<T>? After all, IEnumerable<T> is just a | |
// generalization of IList<T>, and regardless of what's backing the IEnumerable<T>, the deserialized | |
// object will expose semantics that are consistent with the original object. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment