Skip to content

Commit 2e409d0

Browse files
Pirmin Mattmannhazzik
Pirmin Mattmann
authored andcommitted
Add support for out/ref Nullable parameters of proxied methods (#1389)
1 parent 8001939 commit 2e409d0

File tree

3 files changed

+41
-20
lines changed

3 files changed

+41
-20
lines changed

src/NHibernate.Test/DynamicProxyTests/ProxiedMembers/Fixture.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@ public virtual void Method2(ref int x)
1414
{
1515
x++;
1616
}
17+
18+
public virtual void Method3(out int? y)
19+
{
20+
y = 4;
21+
}
22+
23+
public virtual void Method4(ref int? y)
24+
{
25+
y++;
26+
}
1727
}
1828

1929
[TestFixture]
@@ -32,6 +42,13 @@ public void Proxy()
3242
x = 4;
3343
c.Method2(ref x);
3444
Assert.AreEqual(5, x);
45+
46+
int? y;
47+
c.Method3(out y);
48+
Assert.AreEqual(4, y);
49+
50+
c.Method4(ref y);
51+
Assert.AreEqual(5, y);
3552
}
3653
}
3754
}

src/NHibernate/Proxy/DynamicProxy/DefaultArgumentHandler.cs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#endregion
88

9+
using System;
910
using System.Reflection;
1011
using System.Reflection.Emit;
1112

@@ -55,12 +56,19 @@ public void PushArguments(ParameterInfo[] methodParameters, ILGenerator IL, bool
5556

5657
if (param.ParameterType.IsByRef)
5758
{
58-
OpCode ldindInstruction;
59-
if(!OpCodesMap.TryGetLdindOpCode(param.ParameterType.GetElementType(), out ldindInstruction))
59+
var unboxedType = param.ParameterType.GetElementType();
60+
if (Nullable.GetUnderlyingType(unboxedType) != null)
6061
{
61-
ldindInstruction = OpCodes.Ldind_Ref;
62+
IL.Emit(OpCodes.Ldobj, unboxedType);
63+
}
64+
else if (OpCodesMap.TryGetLdindOpCode(unboxedType, out var ldind))
65+
{
66+
IL.Emit(ldind);
67+
}
68+
else
69+
{
70+
IL.Emit(OpCodes.Ldind_Ref);
6271
}
63-
IL.Emit(ldindInstruction);
6472
}
6573

6674
if (parameterType.IsValueType || param.ParameterType.IsByRef || parameterType.IsGenericParameter)
@@ -78,4 +86,4 @@ public void PushArguments(ParameterInfo[] methodParameters, ILGenerator IL, bool
7886

7987
#endregion
8088
}
81-
}
89+
}

src/NHibernate/Proxy/DynamicProxy/DefaultMethodEmitter.cs

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -142,23 +142,19 @@ private static void SaveRefArguments(ILGenerator IL, ParameterInfo[] parameters)
142142

143143
IL.Emit(OpCodes.Unbox_Any, unboxedType);
144144

145-
OpCode stind = GetStindInstruction(param.ParameterType);
146-
IL.Emit(stind);
147-
}
148-
}
149-
150-
private static OpCode GetStindInstruction(System.Type parameterType)
151-
{
152-
if (parameterType.IsByRef)
153-
{
154-
OpCode stindOpCode;
155-
if(OpCodesMap.TryGetStindOpCode(parameterType.GetElementType(), out stindOpCode))
145+
if (Nullable.GetUnderlyingType(unboxedType) != null)
156146
{
157-
return stindOpCode;
147+
IL.Emit(OpCodes.Stobj, unboxedType);
148+
}
149+
else if (OpCodesMap.TryGetStindOpCode(param.ParameterType.GetElementType(), out var stind))
150+
{
151+
IL.Emit(stind);
152+
}
153+
else
154+
{
155+
IL.Emit(OpCodes.Stind_Ref);
158156
}
159157
}
160-
161-
return OpCodes.Stind_Ref;
162158
}
163159

164160
private static void PushTargetMethodInfo(ILGenerator IL, MethodBuilder generatedMethod, MethodInfo method)
@@ -247,4 +243,4 @@ private void PackageReturnType(MethodInfo method, ILGenerator IL)
247243
IL.Emit(OpCodes.Unbox_Any, returnType);
248244
}
249245
}
250-
}
246+
}

0 commit comments

Comments
 (0)