遇CS8790:Lambda/表达式树中替代.NET from-end索引器的方案
问题:Moq中使用从末尾索引器判断文件后缀报错的替代方案
我为测试编写了一个Mock,用于模拟处理任意后缀为.jpg的上传文件的方法。为方便通过文件名判断是否为JPEG文件,我使用了.NET的从末尾索引器表达式,但编译器报错:CS8790: An expression tree may not contain a pattern System.Index or System.Range indexer access. 请问有哪些可达到相同效果且易用的替代方案?
无法运行的代码:
_mock.Setup(f => f.DownloadFileAsync( It.IsNotNull<Guid>(), It.Is<string>(s => s.Split('.', StringSplitOptions.None)[^1] == "jpg"), // CS8790 Error It.IsAny<CancellationToken>())) .Returns(Task.FromResult(new BinaryData(Array.Empty<byte>())));
可正常编译的代码(使用普通索引):
_mock.Setup(f => f.DownloadFileAsync( It.IsNotNull<Guid>(), It.Is<string>(s => s.Split('.', StringSplitOptions.None)[1] == "jpg"), // compiles fine. It.IsAny<CancellationToken>())) .Returns(Task.FromResult(new BinaryData(Array.Empty<byte>())));
替代方案
1. 使用Path.GetExtension(推荐)
这是.NET中专门用于获取文件扩展名的API,能处理各种边缘场景(如文件名含多个点、无后缀等),代码更简洁鲁棒:
_mock.Setup(f => f.DownloadFileAsync( It.IsNotNull<Guid>(), It.Is<string>(s => Path.GetExtension(s).Equals(".jpg", StringComparison.OrdinalIgnoreCase)), It.IsAny<CancellationToken>())) .Returns(Task.FromResult(new BinaryData(Array.Empty<byte>())));
添加StringComparison.OrdinalIgnoreCase可兼容.JPG、.Jpg等大小写变体,适配更多实际场景。
2. 传统索引取最后一项
如果不想依赖Path类,可通过数组长度-1的方式获取最后一个拆分项,同时增加数组长度判断避免索引越界:
_mock.Setup(f => f.DownloadFileAsync( It.IsNotNull<Guid>(), It.Is<string>(s => { var parts = s.Split('.', StringSplitOptions.None); return parts.Length > 0 && parts[parts.Length - 1] == "jpg"; }), It.IsAny<CancellationToken>())) .Returns(Task.FromResult(new BinaryData(Array.Empty<byte>())));
3. 使用EndsWith直接判断
简单直接,通过字符串结尾匹配实现需求,同样推荐忽略大小写:
_mock.Setup(f => f.DownloadFileAsync( It.IsNotNull<Guid>(), It.Is<string>(s => s.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase)), It.IsAny<CancellationToken>())) .Returns(Task.FromResult(new BinaryData(Array.Empty<byte>())));
内容的提问来源于stack exchange,提问作者terrible-coder
相关产品推荐
相关产品推荐

