Использование оператора 'is' с кортежами типа value дает ошибку

Я пытаюсь проверить, является ли переменная object (int, int) и если да, то я буду использовать приведенную переменную, поэтому я попробовал приведенные ниже коды:

//this one gives the error
public void MyMethodWithIs(object val)
{
    if(val is (int id, int name) pair)
    {
        ConsoleWriteLine($"{pair.id}, {pair.name}");
    }
}

//This one works
public void MyMethodWithAs(object val)
{
    var pair = val as (int id, int name)?;
    if(pair!=null)
    {
        ConsoleWriteLine($"{pair.id}, {pair.name}");
    }
}

Метод MyMethodWithIs выдает ошибку ниже в редакторе:

Не найдено подходящего экземпляра или метода расширения для типа

Мой вопрос

Почему один работает нормально, а другой выдает ошибку вообще? Я думаю, что MyMethodWithIs более удобочитаемым и подходящим для использования в моем случае, но я не могу использовать его из-за ошибки.

Ответ 1

Используя возможности сопоставления с образцом С# 8, вы можете написать это:

if (val is (int id, int name))
{
    Console.WriteLine($"id: {id}; name: {name}");
}

Однако это поле id и name, что удивительно. Есть предложение по оптимизации этого.

Ниже С# 8 вы можете написать это:

if (val is ValueTuple<int, int> pair)
{
    Console.WriteLine($"id: {pair.Item1}; name: {pair.Item2}");
}

Конечно, вы можете сделать это немного яснее:

if (val is ValueTuple<int, int> pair)
{
    var (id, name) = pair;
    Console.WriteLine($"id: {id}; name: {name}");
}

Похоже, вы также можете деконструировать встроенный ValueTuple:

if (val is ValueTuple<int, int>(var id, var name))
{
    Console.WriteLine($"id: {id}; name: {name}");
}

... что несколько ужасно, но кажется законным.

Я мог бы ожидать, что val is (int, int) pair) будет работать, но, похоже, никто не разработал этот случай (пока).