为什么没有捕获的 lambda 从 C# 5 中的静态更改为 C# 6 中的实例方法? [英] Why has a lambda with no capture changed from a static in C# 5 to an instance method in C# 6?
问题描述
此代码在标记的行上抛出异常:
This code throws an exception on the marked line:
using System;
using System.Linq.Expressions;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
Action<int, int> a = (x, y) => Console.WriteLine(x + y);
ParameterExpression p1 = Expression.Parameter(typeof(int), "p1");
ParameterExpression p2 = Expression.Parameter(typeof(int), "p2");
// Here is the exception ArgumentNullException.
MethodCallExpression call = Expression.Call(a.Method, p1, p2);
}
}
}
现在,我已经在 VS2013(就像一个魅力)和 VS2015 社区(抛出异常)中测试了这段代码.
Now, I've tested this code in VS2013 (works like a charm) and in VS2015 Community (throws the exception).
我遵循了 .Net 参考源,这导致一些代码条件检查提供的方法是否IsStatic
.
I followed the .Net Reference Source, which led me to some code condition which checkes whether the supplied method IsStatic
or not.
就我而言,我传递的方法 (a.Method
) 在 VS2013 中是静态的,出于某种原因,在 VS2015 中是 非静态(实例).如果没有,它会抛出,告诉我我没有提供 Instance
参数.
In my case, the method I pass (a.Method
) is static in VS2013 and for some reason non static (instance) in VS2015. If not, it throws, telling me that I did not supply the Instance
argument.
为什么会这样?如何避免这种情况,以便 Expression.Call
在新的 Visual Studio 中重新开始工作?
Why is it so? How can this be avoided so that Expression.Call
would begin to work again in new Visual Studio?
推荐答案
我不知道为什么会这样(也在本地复制).
I don't have an answer as to why that is so (reproduced locally, too).
然而,答案是:
为什么会这样?如何避免这种情况,以便 Expression.Call重新开始在新的 Visual Studio 中工作?
Why is it so? How can this be avoided so that Expression.Call would begin to work again in new Visual Studio?
您可以这样做(适用于两种编译器):
You can do this (works on both compilers):
Action<int, int> a = (x, y) => Console.WriteLine(x + y);
ParameterExpression p1 = Expression.Parameter(typeof(int), "p1");
ParameterExpression p2 = Expression.Parameter(typeof(int), "p2");
MethodCallExpression call;
if (a.Method.IsStatic)
{
call = Expression.Call(a.Method, p1, p2);
}
else
{
call = Expression.Call(Expression.Constant(a.Target), a.Method, p1, p2);
}
感谢 Jeppe Stig Nielsen 修复了 a.Target
这篇关于为什么没有捕获的 lambda 从 C# 5 中的静态更改为 C# 6 中的实例方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!