gpt4 book ai didi

c# - 为什么方法类型推断无法推断类型参数?

转载 作者:太空狗 更新时间:2023-10-29 22:04:28 25 4
gpt4 key购买 nike

我不太确定如何使这个问题可读/可理解,但请听我说完,我希望当我们结束时你能理解我的问题(至少,它很容易重现)。

我尝试调用一个用于验证单元测试结果的方法。它具有以下签名:

void AssertPropertyValues<TEnumerable, TElement, TProperty>(
TEnumerable enumerable,
Func<TElement, TProperty> propertyPointer,
params TProperty[] expectedValues)
where TEnumerable : System.Collections.Generic.IList<TElement>

这意味着,它接受以下输入

  1. 任何可枚举的对象,并且包含与 2 的输入相同类型的对象。
  2. 一个 Func(通常封装 lambda 表达式),它采用与 1) 的“内容”相同类型的对象,并返回与 3) 中提供的数组内容的类型相同类型的对象。
  3. 与 2) 中 Func 的输出类型相同的对象数组。

因此,此方法的实际执行可能如下所示:

AssertPropertyValues(
item.ItemGroups,
itemGroup => itemGroup.Name,
"Name1", "Name2", "Name3");

至少,这就是我希望它看起来的样子,但我遇到了众所周知的编译器错误:“无法从用法中推断出方法‘X’的类型参数。”,这就是我不明白。据我所知,它应该包含所有需要的信息,或者它可能是“协变与逆变”问题的另一个版本?

所以现在我不得不这样做:

AssertPropertyValues(
item.ItemGroups,
(ItemGroup itemGroup) => itemGroup.Name,
"Name1", "Name2", "Name3");

谁能指出为什么编译器无法推断出这种情况?

最佳答案

您的问题是由于约束不被视为签名的一部分并且在类型推断期间从未用于进行推论而引起的。您期望推理进行:

  • TEnumerable通过采用第一个参数的类型来确定。
  • TElement通过取 IList<T> 来确定来自 TElement 的实现信息
  • TProperty由 lambda 的主体类型决定

但 C# 从未进行第二步,因为这需要考虑来自约束的信息。正如您所注意到的,如果您在 lambda 中提供该信息,那么编译器会根据形式参数类型进行推导。

幸运的是,您的约束完全没有必要。重写您的方法以获得没有约束的更简单的签名:

void AssertPropertyValues<TElement, TProperty>(
IList<TElement> sequence,
Func<TElement, TProperty> projection,
params TProperty[] expectedValues)

现在你应该没事了。

当您使用它时,您可能应该将其简化为 IEnumerable<TElement>除非你需要 IList<T>因为某些原因。

关于c# - 为什么方法类型推断无法推断类型参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17677451/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com