编辑
在运行和调试之后我来到这个 - 不,我仍然不知道问题到底是什么但是 - 它与表达式有关,这个调用在执行时会生成两种不同类型的表达式
当你使用
Func(new TypeA[] { new TypeA("value") });
它产生
{() => Invoke(Call(VarRef("obj"), value(Demo.Program+<>c__DisplayClass1).m.Name),new [] {new TypeA("value")})}
当你使用
TypeA [] v = new TypeA[] { new TypeA("value") };
Func(v);
它产生
{() => Invoke(Call(VarRef("obj"), value(Demo.Program+<>c__DisplayClass1).m.Name),value(Demo.Program+<>c__DisplayClass1).v)}
注意区别
new [] {new TypeA("value")}
对比
value(Demo.Program+<>c__DisplayClass1).v
其中 Demo 是命名空间的名称,Program 是类,而 v 是变量
编辑 2.2
为了解释更多,我制作了这个示例应用程序
using System;
using System.Linq.Expressions;
namespace TestXml
{
public class MyClass
{
public string Value { get; set; }
public MyClass(string value)
{
Value = value;
}
public override string ToString()
{
return Value;
}
}
class Program
{
static void Main(string[] args)
{
MyClass[] parameter = new MyClass[] { new MyClass("1") };
execute(() => TestInput( new MyClass[] { new MyClass("1") }));
execute(() => TestInput(parameter));
}
public static void TestInput(params object[] parameters)
{
if (parameters != null && parameters.Length > 0) Console.WriteLine(parameters.GetType().FullName);
}
public static void execute(Expression<Action> exp)
{
Console.WriteLine(exp);
}
public delegate void ParamsDelegate(params object[] param);
}
}
输出
() => TestInput(new [] {new MyClass("1")})
() => TestInput(value(TestXml.Program+<>c__DisplayClass0).parameter)
编辑 3
要知道行为差异的原因,我在 MSDN 上提出了这个问题并得到了这个答案:
“执行(()=> TestInput(新MyClass[] {新MyClass(“1”)}));”
不捕获任何东西,lambda 表达式不使用任何变量。
“捕获指向参数变量的指针?”
我想你可以这么说。它不是真正的指针,变量参数存储在对象字段中而不是存储在堆栈中,您看到的 c__DisplayClass0 是编译器生成的用于保存参数变量的类
这导致说这主要是 LinqToCodeDom 如何评估表达式的错误,似乎他们没有处理这种情况。