There are 3 ways of adding items to most lists...
Add(SomeType)
IList<T>.Add(T)
interfaceIList.Add(object)
interface methodand you normally expect them to behave more or less the same. However, LINQ's EntitySet<T>
is... peculiar on both 3.5 and 4.0; the IList
API does not flag the set as "assigned" - the other two mechanisms do - this sounds trivial, but it is important in that it heavily influences serialization (i.e. causes it to be skipped) in the boilerplate code.
Example:
EntitySet<string> set1 = new EntitySet<string>();
set1.Add("abc");
Debug.Assert(set1.Count == 1); // pass
Debug.Assert(set1.HasLoadedOrAssignedValues, "direct"); // pass
EntitySet<string> set2 = new EntitySet<string>();
IList<string> typedList = set2;
typedList.Add("abc");
Debug.Assert(set2.Count == 1); // pass
Debug.Assert(set2.HasLoadedOrAssignedValues, "typed list"); // pass
EntitySet<string> set3 = new EntitySet<string>();
IList untypedList = set3;
untypedList.Add("abc");
Debug.Assert(set3.Count == 1); // pass
Debug.Assert(set3.HasLoadedOrAssignedValues, "untyped list"); // FAIL
Now... this is deeply surprising to me; so much so that it took me over 2 hours of tracking upwards through code to isolate what was happening. So...
is there any sane reason for this? Or is this just a bug?
(FWIW, there was also an issue in set.Assign(set)
in 3.5, but this is now fixed in 4.0.)
Interestingly, this has been identified for several versions now (you stated that a 3.5 issue was fixed in 4.0). Here is a post from 2007. The rest of the IList
methods in 4.0 are correctly tied to the IList<T>
methods. I think that there are 2 likely explanations (of the bug/feature variety):
HasLoadedOrAssignedValues
.It is probably both - a bug that other code inside the framework is counting on. Sounds like someone said to themselves:
No one is really going to cast this into an IList and then call the Add method, right?