-Fixed DynamicReflectionDelegateFactory creating typed value type constructors

This commit is contained in:
James Newton-King
2016-07-20 14:09:56 +12:00
parent 7ac27587c0
commit 6d7ac14313
3 changed files with 44 additions and 5 deletions
@@ -193,6 +193,29 @@ namespace Newtonsoft.Json.Tests.Utilities
Assert.AreEqual("Name!", (string)result);
}
[Test]
public void ConstructorStruct()
{
Func<object> creator1 = DynamicReflectionDelegateFactory.Instance.CreateDefaultConstructor<object>(typeof(MyStruct));
MyStruct myStruct1 = (MyStruct)creator1.Invoke();
Assert.AreEqual(0, myStruct1.IntProperty);
Func<MyStruct> creator2 = DynamicReflectionDelegateFactory.Instance.CreateDefaultConstructor<MyStruct>(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; }
}
}
}
@@ -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<object> creator1 = ExpressionReflectionDelegateFactory.Instance.CreateDefaultConstructor<object>(typeof(MyStruct));
MyStruct myStruct1 = (MyStruct)creator1.Invoke();
Assert.AreEqual(0, myStruct1.IntProperty);
Func<MyStruct> creator2 = ExpressionReflectionDelegateFactory.Instance.CreateDefaultConstructor<MyStruct>(typeof(MyStruct));
MyStruct myStruct2 = creator2.Invoke();
Assert.AreEqual(0, myStruct2.IntProperty);
}
}
}
@@ -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<T>)dynamicMethod.CreateDelegate(typeof(Func<T>));
}
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)
{