diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj
index f3ed4cbd..5ed093f4 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj
@@ -72,6 +72,7 @@
+
@@ -121,6 +122,8 @@
+
+
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj
index 3f4481b7..fc9537b0 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj
@@ -72,6 +72,7 @@
+
@@ -86,6 +87,8 @@
+
+
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj
index d4fdb92d..2f18bb4c 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj
@@ -78,6 +78,7 @@
+
@@ -127,6 +128,8 @@
+
+
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
index 5c49108c..a5de0bab 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
@@ -109,6 +109,9 @@
+
+
+
diff --git a/Src/Newtonsoft.Json.Tests/PerformanceTests.cs b/Src/Newtonsoft.Json.Tests/PerformanceTests.cs
index 7bb208aa..0cccbdae 100644
--- a/Src/Newtonsoft.Json.Tests/PerformanceTests.cs
+++ b/Src/Newtonsoft.Json.Tests/PerformanceTests.cs
@@ -167,7 +167,7 @@ namespace Newtonsoft.Json.Tests
timed.Stop();
- Console.WriteLine("Serialize method: {0}", method);
+ Console.WriteLine("Deserialize method: {0}", method);
Console.WriteLine("{0} ms", timed.ElapsedMilliseconds);
Console.WriteLine(value);
Console.WriteLine();
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/ConstructorHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/ConstructorHandlingTests.cs
new file mode 100644
index 00000000..321da26f
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/Serialization/ConstructorHandlingTests.cs
@@ -0,0 +1,58 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using NUnit.Framework;
+
+namespace Newtonsoft.Json.Tests.Serialization
+{
+ public class ConstructorHandlingTests : TestFixtureBase
+ {
+ [Test]
+ [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Unable to find a constructor to use for type Newtonsoft.Json.Tests.Serialization.PrivateConstructorTestClass. A class should either have a default constructor or only one constructor with arguments.")]
+ public void FailWithPrivateConstructorAndDefault()
+ {
+ string json = @"{Name:""Name!""}";
+
+ JsonConvert.DeserializeObject(json);
+ }
+
+ [Test]
+ public void SuccessWithPrivateConstructorAndAllowNonPublic()
+ {
+ string json = @"{Name:""Name!""}";
+
+ PrivateConstructorTestClass c = JsonConvert.DeserializeObject(json,
+ new JsonSerializerSettings
+ {
+ ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
+ });
+ Assert.IsNotNull(c);
+ Assert.AreEqual("Name!", c.Name);
+ }
+
+ [Test]
+ [ExpectedException(typeof(TargetInvocationException))]
+ public void FailWithPrivateConstructorPlusParametizedAndDefault()
+ {
+ string json = @"{Name:""Name!""}";
+
+ PrivateConstructorWithPublicParametizedConstructorTestClass c = JsonConvert.DeserializeObject(json);
+ }
+
+ [Test]
+ public void SuccessWithPrivateConstructorPlusParametizedAndAllowNonPublic()
+ {
+ string json = @"{Name:""Name!""}";
+
+ PrivateConstructorWithPublicParametizedConstructorTestClass c = JsonConvert.DeserializeObject(json,
+ new JsonSerializerSettings
+ {
+ ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
+ });
+ Assert.IsNotNull(c);
+ Assert.AreEqual("Name!", c.Name);
+ Assert.AreEqual(1, c.Age);
+ }
+ }
+}
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
index ae50dffc..eaa03aa7 100644
--- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
+++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
@@ -1756,7 +1756,7 @@ keyword such as type of business.""
}
[Test]
- [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Unable to determine which constructor to use for type Newtonsoft.Json.Tests.TestObjects.Event. A class with no default constructor should have only one constructor with arguments.")]
+ [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Unable to find a constructor to use for type Newtonsoft.Json.Tests.TestObjects.Event. A class should either have a default constructor or only one constructor with arguments.")]
public void FailWhenClassWithNoDefaultConstructorHasMultipleConstructorsWithArguments()
{
string json = @"{""sublocation"":""AlertEmailSender.Program.Main"",""userId"":0,""type"":0,""summary"":""Loading settings variables"",""details"":null,""stackTrace"":"" at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)\r\n at System.Environment.get_StackTrace()\r\n at mr.Logging.Event..ctor(String summary) in C:\\Projects\\MRUtils\\Logging\\Event.vb:line 71\r\n at AlertEmailSender.Program.Main(String[] args) in C:\\Projects\\AlertEmailSender\\AlertEmailSender\\Program.cs:line 25"",""tag"":null,""time"":""\/Date(1249591032026-0400)\/""}";
diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorTestClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorTestClass.cs
new file mode 100644
index 00000000..ad52d170
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorTestClass.cs
@@ -0,0 +1,37 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+ public class PrivateConstructorTestClass
+ {
+ public string Name { get; set; }
+ public int Age { get; set; }
+
+ private PrivateConstructorTestClass()
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorWithPublicParametizedConstructorTestClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorWithPublicParametizedConstructorTestClass.cs
new file mode 100644
index 00000000..8572ec64
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorWithPublicParametizedConstructorTestClass.cs
@@ -0,0 +1,45 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+ public class PrivateConstructorWithPublicParametizedConstructorTestClass
+ {
+ public string Name { get; set; }
+ public int Age { get; set; }
+
+ private PrivateConstructorWithPublicParametizedConstructorTestClass()
+ {
+ Age = 1;
+ }
+
+ public PrivateConstructorWithPublicParametizedConstructorTestClass(string dummy)
+ {
+ throw new Exception("Should never get here.");
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json/ConstructorHandling.cs b/Src/Newtonsoft.Json/ConstructorHandling.cs
new file mode 100644
index 00000000..591d1508
--- /dev/null
+++ b/Src/Newtonsoft.Json/ConstructorHandling.cs
@@ -0,0 +1,47 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json
+{
+ ///
+ /// Specifies how constructors are used when initializing objects during deserialization by the .
+ ///
+ public enum ConstructorHandling
+ {
+ ///
+ /// First attempt to use the public default constructor then fall back to single paramatized constructor.
+ ///
+ Default = 0,
+ ///
+ /// Allow Json.NET to use a non-public default constructor.
+ ///
+ AllowNonPublicDefaultConstructor = 1
+ }
+}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json/JsonSerializer.cs b/Src/Newtonsoft.Json/JsonSerializer.cs
index 9084247d..f3babd7d 100644
--- a/Src/Newtonsoft.Json/JsonSerializer.cs
+++ b/Src/Newtonsoft.Json/JsonSerializer.cs
@@ -47,6 +47,7 @@ namespace Newtonsoft.Json
private ObjectCreationHandling _objectCreationHandling;
private NullValueHandling _nullValueHandling;
private DefaultValueHandling _defaultValueHandling;
+ private ConstructorHandling _constructorHandling;
private JsonConverterCollection _converters;
private IContractResolver _contractResolver;
private IReferenceResolver _referenceResolver;
@@ -204,6 +205,22 @@ namespace Newtonsoft.Json
}
}
+ ///
+ /// Gets or sets how constructors are used during deserialization.
+ ///
+ /// The constructor handling.
+ public virtual ConstructorHandling ConstructorHandling
+ {
+ get { return _constructorHandling; }
+ set
+ {
+ if (value < ConstructorHandling.Default || value > ConstructorHandling.AllowNonPublicDefaultConstructor)
+ throw new ArgumentOutOfRangeException("value");
+
+ _constructorHandling = value;
+ }
+ }
+
///
/// Gets a collection that will be used during serialization.
///
@@ -247,6 +264,7 @@ namespace Newtonsoft.Json
_defaultValueHandling = JsonSerializerSettings.DefaultDefaultValueHandling;
_objectCreationHandling = JsonSerializerSettings.DefaultObjectCreationHandling;
_preserveReferencesHandling = JsonSerializerSettings.DefaultPreserveReferencesHandling;
+ _constructorHandling = JsonSerializerSettings.DefaultConstructorHandling;
_typeNameHandling = JsonSerializerSettings.DefaultTypeNameHandling;
_binder = DefaultSerializationBinder.Instance;
}
@@ -272,6 +290,7 @@ namespace Newtonsoft.Json
jsonSerializer.ObjectCreationHandling = settings.ObjectCreationHandling;
jsonSerializer.NullValueHandling = settings.NullValueHandling;
jsonSerializer.DefaultValueHandling = settings.DefaultValueHandling;
+ jsonSerializer.ConstructorHandling = settings.ConstructorHandling;
if (settings.ContractResolver != null)
jsonSerializer.ContractResolver = settings.ContractResolver;
diff --git a/Src/Newtonsoft.Json/JsonSerializerSettings.cs b/Src/Newtonsoft.Json/JsonSerializerSettings.cs
index 03d49ecb..f247ba0f 100644
--- a/Src/Newtonsoft.Json/JsonSerializerSettings.cs
+++ b/Src/Newtonsoft.Json/JsonSerializerSettings.cs
@@ -19,6 +19,7 @@ namespace Newtonsoft.Json
internal const DefaultValueHandling DefaultDefaultValueHandling = DefaultValueHandling.Include;
internal const ObjectCreationHandling DefaultObjectCreationHandling = ObjectCreationHandling.Auto;
internal const PreserveReferencesHandling DefaultPreserveReferencesHandling = PreserveReferencesHandling.None;
+ internal const ConstructorHandling DefaultConstructorHandling = ConstructorHandling.Default;
internal const TypeNameHandling DefaultTypeNameHandling = TypeNameHandling.None;
///
@@ -61,6 +62,11 @@ namespace Newtonsoft.Json
///
/// The type name handling.
public TypeNameHandling TypeNameHandling { get; set; }
+ ///
+ /// Gets or sets how constructors are used during deserialization.
+ ///
+ /// The constructor handling.
+ public ConstructorHandling ConstructorHandling { get; set; }
///
/// Gets or sets the contract resolver used by the serializer when
diff --git a/Src/Newtonsoft.Json/JsonTextReader.cs b/Src/Newtonsoft.Json/JsonTextReader.cs
index 697cbad5..83d4e981 100644
--- a/Src/Newtonsoft.Json/JsonTextReader.cs
+++ b/Src/Newtonsoft.Json/JsonTextReader.cs
@@ -347,6 +347,10 @@ namespace Newtonsoft.Json
SetStateBasedOnCurrent();
ClearCurrentChar();
return false;
+ case ' ':
+ // eat whitespace
+ ClearCurrentChar();
+ break;
default:
if (char.IsWhiteSpace(_currentChar))
{
@@ -379,6 +383,9 @@ namespace Newtonsoft.Json
case ',':
SetToken(JsonToken.Undefined);
return true;
+ case ' ':
+ // eat
+ break;
default:
if (char.IsWhiteSpace(_currentChar))
{
@@ -547,6 +554,9 @@ namespace Newtonsoft.Json
case ')':
SetToken(JsonToken.EndConstructor);
return true;
+ case ' ':
+ // eat
+ break;
default:
if (char.IsWhiteSpace(_currentChar))
{
@@ -571,7 +581,7 @@ namespace Newtonsoft.Json
private bool EatWhitespace(bool oneOrMore)
{
bool whitespace = false;
- while (char.IsWhiteSpace(_currentChar))
+ while (_currentChar == ' ' || char.IsWhiteSpace(_currentChar))
{
whitespace = true;
MoveNext();
@@ -736,6 +746,8 @@ namespace Newtonsoft.Json
if (CurrentState == State.Constructor || CurrentState == State.ConstructorStart)
return true;
break;
+ case ' ':
+ return true;
default:
if (char.IsWhiteSpace(_currentChar))
return true;
diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj
index 7e4bb94c..765c1d0d 100644
--- a/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj
+++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj
@@ -57,6 +57,7 @@
+
diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj
index 9c118e63..160d3cdb 100644
--- a/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj
+++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj
@@ -77,6 +77,7 @@
+
diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj
index 711475c5..e811cb9b 100644
--- a/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj
+++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj
@@ -49,6 +49,7 @@
+
diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.csproj
index 78f2b6e3..81ff65ee 100644
--- a/Src/Newtonsoft.Json/Newtonsoft.Json.csproj
+++ b/Src/Newtonsoft.Json/Newtonsoft.Json.csproj
@@ -90,6 +90,7 @@
+
diff --git a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
index cd29f0da..d8ada149 100644
--- a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
+++ b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
@@ -140,10 +140,22 @@ namespace Newtonsoft.Json.Serialization
contract.MemberSerialization = JsonTypeReflector.GetObjectMemberSerialization(objectType);
contract.Properties.AddRange(CreateProperties(contract));
+ if (contract.DefaultContstructor == null || contract.DefaultContstructor.IsPrivate)
+ contract.ParametrizedConstructor = GetParametrizedConstructor(objectType);
return contract;
}
+ private ConstructorInfo GetParametrizedConstructor(Type objectType)
+ {
+ ConstructorInfo[] constructors = objectType.GetConstructors(BindingFlags.Public | BindingFlags.Instance);
+
+ if (constructors.Length == 1)
+ return constructors[0];
+ else
+ return null;
+ }
+
private void InitializeContract(JsonContract contract)
{
JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(contract.UnderlyingType);
@@ -161,6 +173,10 @@ namespace Newtonsoft.Json.Serialization
}
#endif
+ contract.DefaultContstructor =
+ ReflectionUtils.GetDefaultConstructor(contract.CreatedType, false) ??
+ ReflectionUtils.GetDefaultConstructor(contract.CreatedType, true);
+
foreach (MethodInfo method in contract.UnderlyingType.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
{
Type prevAttributeType = null;
diff --git a/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs b/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs
index 96208634..abe216bc 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs
@@ -25,7 +25,9 @@
using System;
using System.Collections.Generic;
+using System.Reflection;
using Newtonsoft.Json.Utilities;
+using System.Collections;
namespace Newtonsoft.Json.Serialization
{
@@ -34,9 +36,13 @@ namespace Newtonsoft.Json.Serialization
///
public class JsonArrayContract : JsonContract
{
- internal Type CollectionTypeToCreate { get; private set; }
internal Type CollectionItemType { get; private set; }
+ private bool _isCollectionItemTypeNullableType;
+ private Type _genericCollectionDefinitionType;
+ private Type _genericWrapperType;
+ private ConstructorInfo _genericWrapperConstructor;
+
///
/// Initializes a new instance of the class.
///
@@ -44,17 +50,40 @@ namespace Newtonsoft.Json.Serialization
public JsonArrayContract(Type underlyingType)
: base(underlyingType)
{
- CollectionItemType = ReflectionUtils.GetCollectionItemType(UnderlyingType);
-
- if (IsTypeGenericCollectionInterface(UnderlyingType))
+ if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(ICollection<>), out _genericCollectionDefinitionType))
{
- Type itemType = ReflectionUtils.GetCollectionItemType(UnderlyingType);
- CollectionTypeToCreate = ReflectionUtils.MakeGenericType(typeof(List<>), itemType);
+ CollectionItemType = _genericCollectionDefinitionType.GetGenericArguments()[0];
}
else
{
- CollectionTypeToCreate = UnderlyingType;
+ CollectionItemType = ReflectionUtils.GetCollectionItemType(UnderlyingType);
}
+
+ if (CollectionItemType != null)
+ _isCollectionItemTypeNullableType = ReflectionUtils.IsNullableType(CollectionItemType);
+
+ if (IsTypeGenericCollectionInterface(UnderlyingType))
+ {
+ CreatedType = ReflectionUtils.MakeGenericType(typeof(List<>), CollectionItemType);
+ }
+ else
+ {
+ CreatedType = UnderlyingType;
+ }
+ }
+
+ internal IWrappedCollection CreateWrapper(object list)
+ {
+ if (list is IList && (CollectionItemType == null || !_isCollectionItemTypeNullableType))
+ return new CollectionWrapper