C# NUnit测试中的lambda和委托类型:编译器错误
我正在写一些单元测试。直接从NUnit's拍摄,我应该可以做这样的事情: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
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的建议,即强制重载解析,强制转换为操作
啊,编译!它没有解释(至少对我来说)为什么带闭包的版本可以正常工作,而不带闭包的版本需要这个。编译器出于某种原因试图绑定到不同的重载。我确信这就是原因,但现在我很想了解它背后的机制。你可能会问一个新问题,显示它试图绑定到哪个过载,以及你希望它绑定到哪个过载。这是个好主意。我会看一看(可能下周吧)。非常感谢。