【问题标题】:Unit testing error System.InvalidCastException:单元测试错误 System.InvalidCastException:
【发布时间】:2026-01-23 18:50:01
【问题描述】:

我正在测试一种方法,该方法从我的存储库中调用一个函数并将其作为列表返回,但我不断收到此错误:

System.InvalidCastException:无法将“System.Collections.Generic.List`1[System.String]”类型的对象转换为“System.String[]”类型。

我不知道我错过了什么。方法如下:

public IList<TransactionStatus> GetBookingStatuses(IList<string> uniqueTransactionRefs)
{
    TransactionStatus[] transactionStatuses = DBRepository.GetStatuses((string[])uniqueTransactionRefs);
    return transactionStatuses;
}

这是我存储库中的方法GetStatuses

TransactionStatus[] GetStatuses(string[] uniqueTransactionRefs);

【问题讨论】:

  • 我认为您需要将 uniqueTransactionRefs 传递给 GetStatuses 方法。

标签: c# unit-testing asp.net-core


【解决方案1】:

IList&lt;string&gt; 是字符串数组 (string[]) 和字符串列表 (List&lt;string&gt;) 都实现的接口。这意味着无论使用哪种底层数据类型,它都是接收多个字符串的理想选择。

在您的情况下,您的方法GetBookingStatusesIList&lt;string&gt; 的形式接收数据,但从错误消息中可以看出,uniqueTransactionRefs 的实际类型是System.Collections.Generic.List`1[System.String],即List&lt;string&gt;。由于这是一个有效的IList&lt;string&gt;,因此将数据传递给该方法可以正常工作。但是当您尝试将其转换为字符串数组时,它将失败,因为List&lt;string&gt;string[] 不直接兼容。

有两种解决方法:

  • 您可以通过调用.ToArray()List&lt;string&gt; 显式转换为字符串数组。这将使用源列表中的元素创建一个新的字符串数组:

    TransactionStatus[] transactionStatuses = DBRepository.GetStatuses(uniqueTransactionRefs.ToArray());
    
  • 根据您的 GetStatuses 方法的作用,您还可以更改其签名,使其不需要字符串数组,但也采用 IList&lt;string&gt;。然后你可以直接从GetBookingStatuses 传入uniqueTransactionRefs 而无需转换:

    TransactionStatus[] transactionStatuses = DBRepository.GetStatuses(uniqueTransactionRefs);
    
    public TransactionStatus[] GetStatuses(IList<string> uniqueTransactionRefs)
    {
        // …
    }
    

【讨论】:

  • 呵呵,有趣,我原以为List&lt;T&gt; 上的ToArray() 会被优化为只返回底层数组而不是复制它,但源代码说你是对的
  • @CamiloTerevinto Afaik,ToArray() 将始终创建一个新数组,以便您可以使用它快速获取原始源无法更改的数组的安全副本。