-Fix to preserve collection type information in certain situations when serializing

-Add missing Newtonsoft.Json.WindowsPhone.sln file
This commit is contained in:
JamesNK
2010-11-17 07:31:20 +00:00
parent 15ea91fb63
commit 5c0431464b
3 changed files with 122 additions and 12 deletions
@@ -3795,11 +3795,11 @@ keyword such as type of business.""
public void DeserializeNullableStruct()
{
NullableStructPropertyClass nullableStructPropertyClass = new NullableStructPropertyClass();
nullableStructPropertyClass.Foo1 = new StructISerializable() {Name = "foo 1"};
nullableStructPropertyClass.Foo2 = new StructISerializable() {Name = "foo 2"};
nullableStructPropertyClass.Foo1 = new StructISerializable() { Name = "foo 1" };
nullableStructPropertyClass.Foo2 = new StructISerializable() { Name = "foo 2" };
NullableStructPropertyClass barWithNull = new NullableStructPropertyClass();
barWithNull.Foo1 = new StructISerializable() {Name = "foo 1"};
barWithNull.Foo1 = new StructISerializable() { Name = "foo 1" };
barWithNull.Foo2 = null;
//throws error on deserialization because bar1.Foo2 is of type Foo?
@@ -3827,5 +3827,63 @@ keyword such as type of business.""
});
}
#endif
[Test]
public void SerializingIEnumerableOfTShouldRetainGenericTypeInfo()
{
CustomEnumerable<Product> products = new CustomEnumerable<Product>();
string json = JsonConvert.SerializeObject(products, Formatting.Indented, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All });
Assert.AreEqual(@"{
""$type"": ""Newtonsoft.Json.Tests.TestObjects.Product[], Newtonsoft.Json.Tests"",
""$values"": []
}", json);
}
public class CustomEnumerable<T> : IEnumerable<T>
{
//NOTE: a simple linked list
private readonly T value;
private readonly CustomEnumerable<T> next;
private readonly int count;
private CustomEnumerable(T value, CustomEnumerable<T> next)
{
this.value = value;
this.next = next;
count = this.next.count + 1;
}
public CustomEnumerable()
{
count = 0;
}
public CustomEnumerable<T> AddFirst(T newVal)
{
return new CustomEnumerable<T>(newVal, this);
}
public IEnumerator<T> GetEnumerator()
{
if (count == 0) // last node
yield break;
yield return value;
var nextInLine = next;
while (nextInLine != null)
{
if (nextInLine.count != 0)
yield return nextInLine.value;
nextInLine = nextInLine.next;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
}
+31
View File
@@ -0,0 +1,31 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Lib", "Lib", "{F69285DD-24FB-4A60-AE8B-4C2744285D0F}"
ProjectSection(SolutionItems) = preProject
Lib\NUnit\Silverlight\nunit.framework.dll = Lib\NUnit\Silverlight\nunit.framework.dll
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Newtonsoft.Json.WindowsPhone", "Newtonsoft.Json\Newtonsoft.Json.WindowsPhone.csproj", "{7A7F70AB-5C07-47ED-BDD2-ECC14DBACA5E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Newtonsoft.Json.Tests.WindowsPhone", "Newtonsoft.Json.Tests\Newtonsoft.Json.Tests.WindowsPhone.csproj", "{5ED71C8C-D0A6-487C-9A8C-BB855ECEAF75}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7A7F70AB-5C07-47ED-BDD2-ECC14DBACA5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7A7F70AB-5C07-47ED-BDD2-ECC14DBACA5E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7A7F70AB-5C07-47ED-BDD2-ECC14DBACA5E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7A7F70AB-5C07-47ED-BDD2-ECC14DBACA5E}.Release|Any CPU.Build.0 = Release|Any CPU
{5ED71C8C-D0A6-487C-9A8C-BB855ECEAF75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5ED71C8C-D0A6-487C-9A8C-BB855ECEAF75}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5ED71C8C-D0A6-487C-9A8C-BB855ECEAF75}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5ED71C8C-D0A6-487C-9A8C-BB855ECEAF75}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
@@ -77,19 +77,40 @@ namespace Newtonsoft.Json.Serialization
if (_genericCollectionDefinitionType != null)
{
if (_genericWrapperType == null)
{
_genericWrapperType = ReflectionUtils.MakeGenericType(typeof (CollectionWrapper<>), CollectionItemType);
ConstructorInfo genericWrapperConstructor = _genericWrapperType.GetConstructor(new[] {_genericCollectionDefinitionType});
_genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(genericWrapperConstructor);
}
EnsureGenericWrapperCreator();
return (IWrappedCollection) _genericWrapperCreator(null, list);
}
else
{
return new CollectionWrapper<object>((IList<object>)((IEnumerable)list).Cast<object>().ToList());
IList values = ((IEnumerable) list).Cast<object>().ToList();
if (CollectionItemType != null)
{
Array array = Array.CreateInstance(CollectionItemType, values.Count);
for (int i = 0; i < values.Count; i++)
{
array.SetValue(values[i], i);
}
values = array;
}
return new CollectionWrapper<object>(values);
}
}
private void EnsureGenericWrapperCreator()
{
if (_genericWrapperType == null)
{
_genericWrapperType = ReflectionUtils.MakeGenericType(typeof (CollectionWrapper<>), CollectionItemType);
Type constructorArgument = (ReflectionUtils.InheritsGenericDefinition(_genericCollectionDefinitionType, typeof (List<>)))
? ReflectionUtils.MakeGenericType(typeof (ICollection<>), CollectionItemType)
: _genericCollectionDefinitionType;
ConstructorInfo genericWrapperConstructor = _genericWrapperType.GetConstructor(new[] { constructorArgument });
_genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(genericWrapperConstructor);
}
}