【问题标题】:Using `is` operator with value type tuples gives error使用带有值类型元组的 `is` 运算符会出错
【发布时间】:2019-05-12 20:22:06
【问题描述】:

我正在尝试检查 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 更具可读性,更适合我的情况,但由于出现错误,我无法使用它。

【问题讨论】:

  • AFAIK 值元组不存储项目名称信息,因此可能无法检查项目是否为 id 和 name。我猜它可能没有名字if (val is (int, int) pair)
  • @Slai 我也试过了,还是出现同样的错误。
  • if (val is ValueTuple<int,string> pair) 虽然有效。有点相关:stackoverflow.com/questions/44706498/…

标签: c# valuetuple


【解决方案1】:

使用 C# 8 的模式匹配功能,您可以这样写:

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

但是这个框 idname,这是令人惊讶的。有一个proposal to optimize this

在 C# 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}");
}

...这有点可怕,但是appears to be legal

我可能预计 val is (int, int) pair) 可以工作,但似乎没有人设计过这个案例(目前)。

【讨论】:

  • 第一个代码块给出了同样的错误。第二个有效,但我不想使用Item1Item2 等。
  • @ilkerkaran 它适用于sharplab - 可能是C# 8 中的新功能。sharplab.io/…
  • @ilkerkaran 找到了另一种方式,添加到我的答案中
  • 我认为我的编辑器还不允许我使用 c#8(我认为是因为它是预览版)。您的更新答案可能是我目前能得到的最接近的答案。
猜你喜欢
  • 2010-12-19
  • 1970-01-01
  • 1970-01-01
  • 2020-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-09
  • 2017-08-28
相关资源
最近更新 更多