Skip to content

Commit b0aeeb3

Browse files
authored
No longer store MethodData in MethodGroupExpression. (#366)
Fix #361
1 parent 15ef85f commit b0aeeb3

File tree

4 files changed

+35
-15
lines changed

4 files changed

+35
-15
lines changed

src/DynamicExpresso.Core/Identifier.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,21 +46,21 @@ public class Overload
4646
{
4747
public Delegate Delegate { get; }
4848

49-
private MethodData _methodData;
50-
public MethodData Method
49+
private MethodBase _method;
50+
public MethodBase Method
5151
{
5252
get
5353
{
54-
if (_methodData == null)
55-
_methodData = MethodData.Gen(Delegate.Method);
54+
if (_method == null)
55+
_method = Delegate.Method;
5656

57-
return _methodData;
57+
return _method;
5858
}
5959
}
6060

6161
// we'll most likely never need this: it was needed before https://github.com/dotnet/roslyn/pull/53402
62-
private MethodData _invokeMethod;
63-
public MethodData InvokeMethod
62+
private MethodBase _invokeMethod;
63+
public MethodBase InvokeMethod
6464
{
6565
get
6666
{
@@ -135,12 +135,12 @@ internal Delegate FindUsedOverload(bool usedInvokeMethod, MethodData methodData)
135135
{
136136
if (usedInvokeMethod)
137137
{
138-
if (overload.InvokeMethod.MethodBase == methodData.MethodBase)
138+
if (methodData.MethodBase == overload.InvokeMethod)
139139
return overload.Delegate;
140140
}
141141
else
142142
{
143-
if (overload.Method.MethodBase == methodData.MethodBase)
143+
if (methodData.MethodBase == overload.Method)
144144
return overload.Delegate;
145145
}
146146
}

src/DynamicExpresso.Core/Parsing/Parser.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,10 +1349,14 @@ private Expression ParseInvocation(Expression expr, int errorPos, string error)
13491349
var args = ParseArgumentList();
13501350

13511351
var invokeMethod = MemberFinder.FindInvokeMethod(expr.Type);
1352-
if (invokeMethod == null || !MethodResolution.CheckIfMethodIsApplicableAndPrepareIt(invokeMethod, args))
1353-
throw ParseException.Create(errorPos, error);
1352+
if (invokeMethod != null)
1353+
{
1354+
var invokeMethodData = MethodData.Gen(invokeMethod);
1355+
if (MethodResolution.CheckIfMethodIsApplicableAndPrepareIt(invokeMethodData, args))
1356+
return Expression.Invoke(expr, invokeMethodData.PromotedParameters);
1357+
}
13541358

1355-
return Expression.Invoke(expr, invokeMethod.PromotedParameters);
1359+
throw ParseException.Create(errorPos, error);
13561360
}
13571361

13581362
private Expression ParseMethodGroupInvocation(MethodGroupExpression methodGroup, int errorPos)
@@ -1378,7 +1382,7 @@ private Expression ParseMethodGroupInvocation(MethodGroupExpression methodGroup,
13781382
if (args.Any(IsDynamicExpression))
13791383
{
13801384
// TODO: we could try to find the best method by using the dynamic binder
1381-
var candidatesWithSameArgumentCount = candidates.Where(_ => _.Method.Parameters.Count == args.Length).ToList();
1385+
var candidatesWithSameArgumentCount = candidates.Where(_ => _.Method.GetParameters().Length == args.Length).ToList();
13821386
if (candidatesWithSameArgumentCount.Count == 1)
13831387
return ParseDynamicMethodGroupInvocation(candidatesWithSameArgumentCount[0].Delegate, args);
13841388
}

src/DynamicExpresso.Core/Reflection/MemberFinder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public IList<MethodData> FindMethods(Type type, string methodName, bool staticAc
5252

5353
// this method is static, because we know that the Invoke method of a delegate always has this exact name
5454
// and therefore we never need to search for it in case-insensitive mode
55-
public static MethodData FindInvokeMethod(Type type)
55+
public static MethodBase FindInvokeMethod(Type type)
5656
{
5757
var flags = BindingFlags.Public | BindingFlags.DeclaredOnly |
5858
BindingFlags.Instance;
@@ -63,7 +63,7 @@ public static MethodData FindInvokeMethod(Type type)
6363
.SingleOrDefault();
6464

6565
if (method != null)
66-
return MethodData.Gen(method);
66+
return method;
6767
}
6868

6969
return null;

test/DynamicExpresso.UnitTest/ThreadingTest.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using System.Collections.Generic;
23
using System.Globalization;
34
using System.Linq;
@@ -92,5 +93,20 @@ public void Should_Fail_Parallel_Eval()
9293
Assert.That(target.Eval(exp, parameters), Is.True);
9394
});
9495
}
96+
97+
[Test]
98+
public void Should_Pass_Parallel_Invoke_MethodGroup()
99+
{
100+
var interpreter = new Interpreter();
101+
102+
Func<IEnumerable<int>, int> minFunc = Enumerable.Min;
103+
interpreter.SetFunction("min", minFunc);
104+
105+
Parallel.ForEach(Enumerable.Range(1, 25), i =>
106+
{
107+
var arguments = new[] { i, i + 1, i + 2 };
108+
Assert.That(interpreter.Eval("min(x)", new Parameter("x", arguments)), Is.EqualTo(i));
109+
});
110+
}
95111
}
96112
}

0 commit comments

Comments
 (0)