-Fixed iterating over extension data multiple times
This commit is contained in:
@@ -624,10 +624,10 @@ namespace Newtonsoft.Json.Tests.Serialization
|
||||
[Test]
|
||||
public void ExtensionDataGetterCanBeIteratedMultipleTimes()
|
||||
{
|
||||
var resolver = new DefaultContractResolver();
|
||||
var contract = (JsonObjectContract)resolver.ResolveContract(typeof(ClassWithExtensionData));
|
||||
DefaultContractResolver resolver = new DefaultContractResolver();
|
||||
JsonObjectContract contract = (JsonObjectContract)resolver.ResolveContract(typeof(ClassWithExtensionData));
|
||||
|
||||
var myClass = new ClassWithExtensionData
|
||||
ClassWithExtensionData myClass = new ClassWithExtensionData
|
||||
{
|
||||
Data = new Dictionary<string, object>
|
||||
{
|
||||
@@ -635,9 +635,13 @@ namespace Newtonsoft.Json.Tests.Serialization
|
||||
}
|
||||
};
|
||||
|
||||
var getter = contract.ExtensionDataGetter;
|
||||
ExtensionDataGetter getter = contract.ExtensionDataGetter;
|
||||
|
||||
var extensionData = getter(myClass);
|
||||
IEnumerable<KeyValuePair<object, object>> dictionaryData = getter(myClass).ToDictionary(kv => kv.Key, kv => kv.Value);
|
||||
Assert.IsTrue(dictionaryData.Any());
|
||||
Assert.IsTrue(dictionaryData.Any());
|
||||
|
||||
IEnumerable<KeyValuePair<object, object>> extensionData = getter(myClass);
|
||||
Assert.IsTrue(extensionData.Any());
|
||||
Assert.IsTrue(extensionData.Any()); // second test fails if the enumerator returned isn't reset
|
||||
}
|
||||
|
||||
@@ -555,7 +555,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
|
||||
if (extensionDataAttribute.WriteData)
|
||||
{
|
||||
Type enumerableWrapper = typeof(DictionaryEnumerator<,>).MakeGenericType(keyType, valueType);
|
||||
Type enumerableWrapper = typeof(EnumerableDictionaryWrapper<,>).MakeGenericType(keyType, valueType);
|
||||
ConstructorInfo constructors = enumerableWrapper.GetConstructors().First();
|
||||
ObjectConstructor<object> createEnumerableWrapper = JsonTypeReflector.ReflectionDelegateFactory.CreateParameterizedConstructor(constructors);
|
||||
|
||||
@@ -576,11 +576,13 @@ namespace Newtonsoft.Json.Serialization
|
||||
contract.ExtensionDataValueType = valueType;
|
||||
}
|
||||
|
||||
internal struct DictionaryEnumerator<TEnumeratorKey, TEnumeratorValue> : IEnumerable<KeyValuePair<object, object>>
|
||||
// leave as class instead of struct
|
||||
// will be always return as an interface and boxed
|
||||
internal class EnumerableDictionaryWrapper<TEnumeratorKey, TEnumeratorValue> : IEnumerable<KeyValuePair<object, object>>
|
||||
{
|
||||
private readonly IEnumerable<KeyValuePair<TEnumeratorKey, TEnumeratorValue>> _e;
|
||||
|
||||
public DictionaryEnumerator(IEnumerable<KeyValuePair<TEnumeratorKey, TEnumeratorValue>> e)
|
||||
public EnumerableDictionaryWrapper(IEnumerable<KeyValuePair<TEnumeratorKey, TEnumeratorValue>> e)
|
||||
{
|
||||
ValidationUtils.ArgumentNotNull(e, nameof(e));
|
||||
_e = e;
|
||||
@@ -588,7 +590,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
|
||||
public IEnumerator<KeyValuePair<object, object>> GetEnumerator()
|
||||
{
|
||||
foreach (var item in _e)
|
||||
foreach (KeyValuePair<TEnumeratorKey, TEnumeratorValue> item in _e)
|
||||
{
|
||||
yield return new KeyValuePair<object, object>(item.Key, item.Value);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user