C# NUnit测试中的lambda和委托类型:编译器错误

C# NUnit测试中的lambda和委托类型:编译器错误,c#,lambda,nunit,C#,Lambda,Nunit,我正在写一些单元测试。直接从NUnit's拍摄,我应该可以做这样的事情: Assert.That(SomeMethod,Throws.ArgumentException); 在测试方法中,这不会编译: Assert.That(()=>viewModel.SaveCommand_Exec(这是新的ExecutedRoutedEventArgs()), 什么都没有); //编译器错误: //无法将lambda表达式转换为类型“bool” //因为它不是委托类型 但这将: ExecutedRout

我正在写一些单元测试。直接从NUnit's拍摄,我应该可以做这样的事情:

Assert.That(SomeMethod,Throws.ArgumentException);
在测试方法中,这不会编译:

Assert.That(()=>viewModel.SaveCommand_Exec(这是新的ExecutedRoutedEventArgs()),
什么都没有);
//编译器错误:
//无法将lambda表达式转换为类型“bool”
//因为它不是委托类型
但这将:

ExecutedRoutedEventArgs e=new ExecutedRoutedEventArgs();
Assert.That(()=>viewModel.SaveCommand_Exec(this,e),抛出.Nothing);
这也将:

Assert.DoesNotThrow(()=>viewModel.SaveCommand\u Exec(此,
新执行的路由EventArgs());
显然,我有两个变通办法,但我有点难以理解这里发生了什么。为什么我可以
new
在lambda中创建一个
ExecutedRoutedEventArgs
,它创建一个委托参数,但不创建另一个委托参数

更有趣的是,在lambda外部而不是内部创建
EventArgs
对象的区别到底是什么?我意识到这会创建一个闭包,但我不明白这是如何改变匿名方法的签名的


我使用的是VS2013,目标是.net 4.0,我没有NUnit需要验证,但可能需要将Lambda显式转换为
委托
,以强制执行正确的重载解决方案:

 Assert.That((Action)(()=>viewModel.SaveCommand_Exec(this, new ExecutedRoutedEventArgs())),
                Throws.Nothing);

我无法访问您在示例中使用的确切类,但以下非常类似的代码在VS 2013 targeting.NET 4中编译并运行良好。您正在使用NUnit 2.6.3吗?此外,您还正确地识别了在lambda外部创建
ExecutedRoutedEventArgs
实例与在lambda内部创建实例之间的唯一区别:闭包

using NUnit.Framework;

namespace ConsoleApplication1
{
    internal class Program
    {
        private static void Main()
        {
            var viewModel = new ViewModel();

            Assert.That(() => viewModel.SaveCommand_Exec(null, new ExecutedRoutedEventArgs()), Throws.Nothing);
        }
    }

    public class ViewModel
    {
        public bool SaveCommand_Exec(object sender, ExecutedRoutedEventArgs e)
        {
            return true;
        }
    }

    public class ExecutedRoutedEventArgs
    {
    }
}

Expect()
是如何定义的?在第二个示例中,为什么要使用它而不是Assert.that()?您使用的是.NET和NUnit的哪个版本?看看他们的发行说明,2.5版本中似乎修复了一个类似的错误。1@swick. 抱歉-剪切/粘贴错误。这是一条并非所有人都使用的NUnit捷径-我的意思是将其编辑为
Asster.that()
完全相同。我已经把它改了question@DStanley:.net 4.0和NUnit 2.6.3(最新版本)多亏了其他贡献者,我现在有了四个变通方法/工作替代版本,但仍然不理解为什么原始版本不起作用!是的,2.6.3。抱歉,我应该提到这一点(我试图尽量减少问题的NUnit方面,因为我更多地将其视为一个语言问题)。我更新了代码示例,使其看起来尽可能像您的代码示例。我仍然没有收到编译器错误,代码执行正常。我唯一能推荐的是,绝对确保您运行的是您认为您运行的NUnit版本,并且您的目标是.NET 4。您和我的区别(显然是问题所在)在于,我会将“this”放在具有
null
的委托中。想必,
这个
仍然指向lambda表达式中的某些内容,但无论如何,我仍然看不到方法签名是如何受到影响的。是的,这肯定不会影响正在创建的委托的签名。试试这个,看看会发生什么:
ActualValueDelegate=()=>viewModel.SaveCommand\u Exec(null,newexecutedRouteDevenTargs());断言(d,抛出。无)我使用ReSharper来提取一个变量。是的,也可以。我想这类似于D Stanley的建议,即强制重载解析,强制转换为
操作
啊,编译!它没有解释(至少对我来说)为什么带闭包的版本可以正常工作,而不带闭包的版本需要这个。编译器出于某种原因试图绑定到不同的重载。我确信这就是原因,但现在我很想了解它背后的机制。你可能会问一个新问题,显示它试图绑定到哪个过载,以及你希望它绑定到哪个过载。这是个好主意。我会看一看(可能下周吧)。非常感谢。