So I have a collection of Tuple that looks like this:
public List<(ElementRowViewModel Parent, ElementBase Element)> ResultCollection { get; private set; } = new List<(ElementRowViewModel Parent, ElementBase Element)>();
When I try to do the following
private async Task RegisterAndCommitElements<TElement>() where TElement : ElementBase
{
var specificElements = this.ResultCollection.OfType<(ElementRowViewModel parent, TElement element)>();
}
It yields nothing. But When I do
this.ResultCollection[0] is (ElementRowViewModel parent, SpecificElement element)
It returns true, Or even
this.ResultCollection[0] is (ElementRowViewModel parent, TElement element)
It also returns true.
Am I miss-understanding something? Or is there a limitation or a known bug with Enumerable.OfType(IEnumerable) when using tuple as type parameter?
A ValueTuple<ElementRowViewModel, SpecificElement>
value isn't a ValueTuple<ElementRowViewModel, ElementBase>
. There's an implicit conversion from one to the other, but that's defined by the C# language (basically it performs element-wise conversion) not by the CLR type system, which is what OfType
cares about.
using System;
public class Test
{
public static void Main(string[] args)
{
var strings = ("hello", "there");
object boxed = strings;
Console.WriteLine(boxed is ValueTuple<string, string>); // True
Console.WriteLine(boxed is ValueTuple<object, object>); // False
// This is still valid though: element-wise implicit conversions.
(object, object) objects = strings;
}
}
That second is
test that returns false is effectively what the OfType
method is doing, so it makes sense that your value isn't yielded.