Fixed an issue where iterating extensionDataGetter's enumerable multiple times or using LINQ statement on it caused inconsistant data to be returned.

This commit is contained in:
Lowell Smith
2016-02-05 15:05:42 -05:00
parent b26bccc4f6
commit 29567c5b5d
2 changed files with 35 additions and 30 deletions
@@ -614,5 +614,32 @@ namespace Newtonsoft.Json.Tests.Serialization
}
#pragma warning restore 618
#endif
public class ClassWithExtensionData
{
[JsonExtensionData]
public IDictionary<string, object> Data { get; set; }
}
[Test]
public void ExtensionDataGetterCanBeIteratedMultipleTimes()
{
var resolver = new DefaultContractResolver();
var contract = (JsonObjectContract)resolver.ResolveContract(typeof(ClassWithExtensionData));
var myClass = new ClassWithExtensionData
{
Data = new Dictionary<string, object>
{
{ "SomeField", "Field" },
}
};
var getter = contract.ExtensionDataGetter;
var extensionData = getter(myClass);
Assert.IsTrue(extensionData.Any());
Assert.IsTrue(extensionData.Any()); // second test fails if the enumerator returned isn't reset
}
}
}
@@ -576,49 +576,27 @@ namespace Newtonsoft.Json.Serialization
contract.ExtensionDataValueType = valueType;
}
internal struct DictionaryEnumerator<TEnumeratorKey, TEnumeratorValue> : IEnumerable<KeyValuePair<object, object>>, IEnumerator<KeyValuePair<object, object>>
internal struct DictionaryEnumerator<TEnumeratorKey, TEnumeratorValue> : IEnumerable<KeyValuePair<object, object>>
{
private readonly IEnumerator<KeyValuePair<TEnumeratorKey, TEnumeratorValue>> _e;
private readonly IEnumerable<KeyValuePair<TEnumeratorKey, TEnumeratorValue>> _e;
public DictionaryEnumerator(IEnumerable<KeyValuePair<TEnumeratorKey, TEnumeratorValue>> e)
{
ValidationUtils.ArgumentNotNull(e, nameof(e));
_e = e.GetEnumerator();
}
public bool MoveNext()
{
return _e.MoveNext();
}
public void Reset()
{
_e.Reset();
}
public KeyValuePair<object, object> Current
{
get { return new KeyValuePair<object, object>(_e.Current.Key, _e.Current.Value); }
}
public void Dispose()
{
_e.Dispose();
}
object IEnumerator.Current
{
get { return Current; }
_e = e;
}
public IEnumerator<KeyValuePair<object, object>> GetEnumerator()
{
return this;
foreach (var item in _e)
{
yield return new KeyValuePair<object, object>(item.Key, item.Value);
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return this;
return GetEnumerator();
}
}