运算符“==”不能应用于 'Task<(IEnumerable<Item>, int)>' 和 'Task<IEnumerable<Item>>' 类型的操作数

Operator '==' cannot be applied to operands of type 'Task<(IEnumerable<Item>, int)>' and 'Task<IEnumerable<Item>>'

我要模拟以下函数。

public interface IRepository
{
    Task<IEnumerable<Item>> GetItems(int total);
}

我的模拟代码是

private readonly IEnumerable<Item> stubList = new List<Item> { new Item { } };

mockRepository = Mock.Of<IRepository>(r => r.GetItems(50) == Task.FromResult(stubList));

它适用于我的桌面 (Visual studio 2017) 和 Jenkin 服务器上的 msbuild (MSBuild auto-detection: using msbuild version '15.8.169.51996' from 'C:\Program Files (x86)\Microsoft Visual Studio17\BuildTools\MSBuild.0\bin')。

现在方法已经改为

public interface IRepository
{
    Task<(IEnumerable<Item>, int)> GetItems(int total);
}

模拟代码更改为

private readonly IEnumerable<Item> stubList = new List<Item> { new Item { } };

var m = (stubList, 1);
mockRepository = Mock.Of<IRepository>(r => r.GetItems(50) == Task.FromResult(m));

它在我的桌面上仍然有效(visual studio 2017)。但是 msbuild 失败并显示以下错误消息?

error CS0019: Operator '==' cannot be applied to operands of type 'Task<(IEnumerable<Item>, int)>' and 'Task<IEnumerable<Item>>'

build.log:

CoreResGen: "C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\Resgen.exe" /useSourcePath /r:"D:\Jenkins\workspace...\packages\DocumentFormat.OpenXml.2.8.1\lib\net35\DocumentFormat.OpenXml.dll" /r:C:\Windows\Microsoft.NET\Framework\v2.0.50727\Microsoft.JScript.dll /r:C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll /r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll" /r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Data.DataSetExtensions.dll" /r:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll /r:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Design.dll /r:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll /r:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Drawing.dll /r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\System.Runtime.Serialization.dll" /r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\System.ServiceModel.dll" /r:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Web.Services.dll /r:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Windows.Forms.dll /r:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Xml.Linq.dll" /r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\WindowsBase.dll" /compile Components\CheckedComboBox\PopupComboBox.resx,obj\Release\PresentationControls.PopupComboBox.resources Components\DGV\DgvDesignerColumnList.resx,obj\Release\Infrastructure.DgvDesignerColumnList.resources Components\DGV\frmGridColumnsExt.resx,obj\Release\Infrastructure.frmGridColumnsExt.resources Components\DGV\dgv.resx,obj\Release\Infrastructure.DGV.resources Components\DGV\frmChangeGridState.resx,obj\Release\Infrastructure.frmChangeGridState.resources Components\DGV\frmGridColumns.resx,obj\Release\Infrastructure.frmGridColumns.resources Components\UserControl_Folder.resx,obj\Release\Infrastructure.UserControl_Folder.resources frmDropDownBox.resx,obj\Release\Infrastructure.frmDropDownBox.resources frmUsersChangeHistory.resx,obj\Release\Infrastructure.frmUsersChangeHistory.resources frmUserPermissions.resx,obj\Release\Infrastructure.frmUserPermissions.resources frmUserRegProdGroups.resx,obj\Release\Infrastructure.frmUserRegProdGroups.resources frmErrorBox.resx,obj\Release\Infrastructure.frmErrorBox.resources frmGridBox.resx,obj\Release\Infrastructure.frmGridBox.resources frmInputBox.resx,obj\Release\Infrastructure.frmInputBox.resources frmLongTask.resx,obj\Release\Infrastructure.frmLongTask.resources frmNoteBox.resx,obj\Release\Infrastructure.frmNoteBox.resources Components\MonthPicker.resx,obj\Release\Infrastructure.MonthPicker.resources frmUserGroups.resx,obj\Release\Infrastructure.frmUserGroups.resources frmUsers.resx,obj\Release\Infrastructure.frmUsers.resources Properties\Resources.resx,obj\Release\Infrastructure.Properties.Resources.resources Reports\frmEditReports.resx,obj\Release\Infrastructure.frmEditReports.resources Reports\frmJobsMaintenance.resx,obj\Release\Infrastructure.frmJobsMaintenance.resources Reports\frmRunReports.resx,obj\Release\Infrastructure.frmRunReports.resources Reports\frmSelectReport.resx,obj\Release\Infrastructure.frmSelectReport.resources Reports\frmShowReportLog.resx,obj\Release\Infrastructure.frmShowReportLog.resources

尝试使用更详细的方法而不是 LINQ to Mocks

private readonly IEnumerable<Item> stubList = new List<Item> { new Item { } };

//...

var expected = (stubList, 1);

var mock = new Mock<IRepository>();
mock
    .Setup(_ => _.GetItems(50))
    .ReturnsAsync(expected); 

IRepository mockRepository = mock.Object;

//...

框架在尝试使用新语法计算表达式时可能遇到问题

当我尝试你的代码时:

class Program
{
    static void Main(string[] args)
    {
        var stubList = new List<Item>
        {
            new Item()
        };

        var m = (stubList, 1);

        var mockRepository = Mock.Of<IRepository>(r => r.GetItems(50) == Task.FromResult(m));
    }
}

interface IRepository
{
    Task<(IEnumerable<Item>, int)> GetItems(int total);
}

class Item
{
}

我遇到不同的编译器错误:

CS0019 Operator '==' cannot be applied to operands of type 'Task<(IEnumerable, int)>' and 'Task<(List stubList, int)>'

发生这种情况是因为您比较了 Task<(List<Item>, int)>Task<(IEnumerable<Item>, int)>Task<T> 不是 co-variant(例如,与 List<T> 相反),因此错误是预期的。

但是为什么你的问题包含不同的编译器错误?


如果我将代码更改为:

var m = ((IEnumerable<Item>)stubList, 1);

或者这个:

(IEnumerable<Item>, int) m = (stubList, 1);

那么它就符合要求了。