From 6d7ac143134850c8ecfc1d20403cd3c16e23cff1 Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Wed, 20 Jul 2016 14:09:56 +1200 Subject: [PATCH] -Fixed DynamicReflectionDelegateFactory creating typed value type constructors --- .../DynamicReflectionDelegateFactoryTests.cs | 23 +++++++++++++++++++ ...xpressionReflectionDelegateFactoryTests.cs | 12 ++++++++++ .../DynamicReflectionDelegateFactory.cs | 14 +++++++---- 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/Src/Newtonsoft.Json.Tests/Utilities/DynamicReflectionDelegateFactoryTests.cs b/Src/Newtonsoft.Json.Tests/Utilities/DynamicReflectionDelegateFactoryTests.cs index 3fc261d0..da447eb8 100644 --- a/Src/Newtonsoft.Json.Tests/Utilities/DynamicReflectionDelegateFactoryTests.cs +++ b/Src/Newtonsoft.Json.Tests/Utilities/DynamicReflectionDelegateFactoryTests.cs @@ -193,6 +193,29 @@ namespace Newtonsoft.Json.Tests.Utilities Assert.AreEqual("Name!", (string)result); } + + [Test] + public void ConstructorStruct() + { + Func creator1 = DynamicReflectionDelegateFactory.Instance.CreateDefaultConstructor(typeof(MyStruct)); + MyStruct myStruct1 = (MyStruct)creator1.Invoke(); + Assert.AreEqual(0, myStruct1.IntProperty); + + Func creator2 = DynamicReflectionDelegateFactory.Instance.CreateDefaultConstructor(typeof(MyStruct)); + MyStruct myStruct2 = creator2.Invoke(); + Assert.AreEqual(0, myStruct2.IntProperty); + } + } + + public struct MyStruct + { + private int _intProperty; + + public int IntProperty + { + get { return _intProperty; } + set { _intProperty = value; } + } } } diff --git a/Src/Newtonsoft.Json.Tests/Utilities/ExpressionReflectionDelegateFactoryTests.cs b/Src/Newtonsoft.Json.Tests/Utilities/ExpressionReflectionDelegateFactoryTests.cs index 7888fd2c..28730208 100644 --- a/Src/Newtonsoft.Json.Tests/Utilities/ExpressionReflectionDelegateFactoryTests.cs +++ b/Src/Newtonsoft.Json.Tests/Utilities/ExpressionReflectionDelegateFactoryTests.cs @@ -362,6 +362,18 @@ namespace Newtonsoft.Json.Tests.Utilities JsonSerializerTest.DictionaryKey key = (JsonSerializerTest.DictionaryKey)result; Assert.AreEqual("First!", key.Value); } + + [Test] + public void ConstructorStruct() + { + Func creator1 = ExpressionReflectionDelegateFactory.Instance.CreateDefaultConstructor(typeof(MyStruct)); + MyStruct myStruct1 = (MyStruct)creator1.Invoke(); + Assert.AreEqual(0, myStruct1.IntProperty); + + Func creator2 = ExpressionReflectionDelegateFactory.Instance.CreateDefaultConstructor(typeof(MyStruct)); + MyStruct myStruct2 = creator2.Invoke(); + Assert.AreEqual(0, myStruct2.IntProperty); + } } } diff --git a/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs b/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs index fdd930b5..43ee712f 100644 --- a/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs +++ b/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs @@ -208,24 +208,28 @@ namespace Newtonsoft.Json.Utilities dynamicMethod.InitLocals = true; ILGenerator generator = dynamicMethod.GetILGenerator(); - GenerateCreateDefaultConstructorIL(type, generator); + GenerateCreateDefaultConstructorIL(type, generator, typeof(T)); return (Func)dynamicMethod.CreateDelegate(typeof(Func)); } - private void GenerateCreateDefaultConstructorIL(Type type, ILGenerator generator) + private void GenerateCreateDefaultConstructorIL(Type type, ILGenerator generator, Type delegateType) { if (type.IsValueType()) { generator.DeclareLocal(type); generator.Emit(OpCodes.Ldloc_0); - generator.Emit(OpCodes.Box, type); + + // only need to box if the delegate isn't returning the value type + if (type != delegateType) + { + generator.Emit(OpCodes.Box, type); + } } else { ConstructorInfo constructorInfo = - type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, - ReflectionUtils.EmptyTypes, null); + type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, ReflectionUtils.EmptyTypes, null); if (constructorInfo == null) {