.net 为什么类型<;是可枚举的;TResult>;(IEnumerable)不';ValueTuple无法按预期工作? 行为
我有一个元组集合,看起来像这样:.net 为什么类型<;是可枚举的;TResult>;(IEnumerable)不';ValueTuple无法按预期工作? 行为,.net,linq,generics,type-parameter,valuetuple,.net,Linq,Generics,Type Parameter,Valuetuple,我有一个元组集合,看起来像这样: public List<(ElementRowViewModel Parent, ElementBase Element)> ResultCollection { get; private set; } = new List<(ElementRowViewModel Parent, ElementBase Element)>(); ITuple tuple = obj as ITuple; Console.WriteLine(tuple
public List<(ElementRowViewModel Parent, ElementBase Element)> ResultCollection { get; private set; } = new List<(ElementRowViewModel Parent, ElementBase Element)>();
ITuple tuple = obj as ITuple;
Console.WriteLine(tuple != null && tuple.Length == 2 && tuple[0] is ElementRowViewModel && tuple[1] is SpecificElement);
它返回true,甚至
this.ResultCollection[0] is (ElementRowViewModel parent, TElement element)
它也返回true
我错过了什么吗?或者当使用tuple作为类型参数时,类型(IEnumerable)的可枚举性是否存在限制或已知错误?aValueTuple
值不是ValueTuple
。有一个从一个到另一个的隐式转换,但这是由C语言定义的(基本上它执行元素转换),而不是由CLR类型系统定义的,这正是类型所关心的
使用系统;
公开课考试
{
公共静态void Main(字符串[]args)
{
var strings=(“hello”,“there”);
装箱对象=字符串;
Console.WriteLine(装箱的是ValueTuple);//True
Console.WriteLine(装箱的是ValueTuple);//False
//但这仍然有效:元素级隐式转换。
(对象,对象)对象=字符串;
}
}
第二个是返回false的测试实际上是type
方法的所做的,因此没有生成值是有意义的。AValueTuple
值不是ValueTuple
。有一个从一个到另一个的隐式转换,但这是由C语言定义的(基本上它执行元素转换),而不是由CLR类型系统定义的,这正是类型
所关心的
使用系统;
公开课考试
{
公共静态void Main(字符串[]args)
{
var strings=(“hello”,“there”);
装箱对象=字符串;
Console.WriteLine(装箱的是ValueTuple);//True
Console.WriteLine(装箱的是ValueTuple);//False
//但这仍然有效:元素级隐式转换。
(对象,对象)对象=字符串;
}
}
第二个是返回false的测试实际上是type
方法的所做的,因此没有生成您的值是有意义的。如果您查看源代码,您将看到它在内部调用,看起来是这样的:
private static IEnumerable<TResult> OfTypeIterator<TResult>(IEnumerable source)
{
foreach (object? obj in source)
{
if (obj is TResult result)
{
yield return result;
}
}
}
您可以通过查看第二个和第三个语句之间的差异
泛型方法只执行“简单”类型测试(使用IL指令),该测试将返回false(导致z
的类型为ValueTuple
,它不等于ValueTuple
)
非泛型检查(z is(ElementRowViewModel,SpecificElement)
)实际上由编译器转换为如下内容:
public List<(ElementRowViewModel Parent, ElementBase Element)> ResultCollection { get; private set; } = new List<(ElementRowViewModel Parent, ElementBase Element)>();
ITuple tuple = obj as ITuple;
Console.WriteLine(tuple != null && tuple.Length == 2 && tuple[0] is ElementRowViewModel && tuple[1] is SpecificElement);
它对每个元组元素执行类型检查,结果是true
如果您查看源代码,您将看到它在内部调用如下所示:
private static IEnumerable<TResult> OfTypeIterator<TResult>(IEnumerable source)
{
foreach (object? obj in source)
{
if (obj is TResult result)
{
yield return result;
}
}
}
您可以通过查看第二个和第三个语句之间的差异
泛型方法只执行“简单”类型测试(使用IL指令),该测试将返回false(导致z
的类型为ValueTuple
,它不等于ValueTuple
)
非泛型检查(z is(ElementRowViewModel,SpecificElement)
)实际上由编译器转换为如下内容:
public List<(ElementRowViewModel Parent, ElementBase Element)> ResultCollection { get; private set; } = new List<(ElementRowViewModel Parent, ElementBase Element)>();
ITuple tuple = obj as ITuple;
Console.WriteLine(tuple != null && tuple.Length == 2 && tuple[0] is ElementRowViewModel && tuple[1] is SpecificElement);
它对每个元组元素执行类型检查,结果为true