使用using关键字声明匿名元组是否可行?

3
using Coordinate = (int x, int y);

无法编译。

using Coordinate = System.Tuple<int, int>;

可以编译。

由于某些原因,我更喜欢前者;这可行吗?

更新:

原因受到了质疑和辩论,以下是原因:

我有一个处理元组的小类。我本可以写一个小的元组class Coord{int x; int y;},但我决定不这样做。相反,我在每个地方都写了(int x, int y),并让鸭子类型发挥其魔力。它运行得很好,但在某些地方阅读起来会有障碍,可能是因为我们习惯将类型读作PascalCase而不是(pare,the,sised)
所以我有一个想法,就像给类型Tuple<int,int>取一个别名一样,我可以给匿名类型(int x, int y)取一个别名。然后我可以根据我认为更易读的方式使用别名或匿名类型。
(我的真实代码比x&y稍微复杂一些)


3
在这个上下文中(即命名空间别名),第一个选项没有意义。在命名空间别名中不会涉及到变量名,我甚至不确定为什么你想要这样做或者它能解决什么问题... - maccettura
1
如果你只想为ValueTuple使用别名,只需使用命名空间:using Coordinate = System.ValueTuple<int, int>;( ... )语法在该上下文中无效,因此您必须实际使用命名空间。 - maccettura
1
我认为,这类似于为什么您无法将可选字符串参数的默认值设置为 string.empty,它需要 ""。第一个元组是语法糖。那里还没有类型。Using 指令需要已知的类型或命名空间。 - T.S.
1
(int x, int y)ValueTuple<int, int> 的简写,但是 带有 有关两个元组项名称的元数据。这是一个完全合法的请求,但编译器不支持它,因为尚未添加支持。 - Lasse V. Karlsen
@T.S. 我认为你的评论是最有信息量的。“第一个元组是语法糖。”虽然我没有找到这样的信息(谷歌技能?),但如果你能提供链接并写出答案,我会标记它。谢谢。 - LosManos
显示剩余2条评论
2个回答

4

前者不能使用,因为它不是有效的C#语法。

即使using Coordinate = System.Tuple<int, int>;编译通过,我仍然建议采用不同的方法来实现您可能想要实现的目标:

public class Coordinate
{
    public Coordinate(int x, int y)
    {
        X = x;
        Y = y;
    }

    public int X { get; set; }
    public int Y { get; set; }
}

var coordinate = new Coordinate(xVariable, yVariable);

您可以通过 coordinate.Xcoordinate.Y 访问您的 XY 变量。

正如maccettura所指出的那样,我应该说明我选择这种方法的原因:

  1. 如果您想稍后更改坐标,则元组会限制您,因为创建后其元素无法修改
  2. 此外,我认为您可能希望添加一些其他功能到您的坐标中,例如使用 ToString() 或其他方法/属性

1
OP在谈论using指令而不是using语句。 - maccettura
2
@maccettura 我认为 Tuple 在长期内会限制 OP,因为他创建后无法写入 Tuple 项。也许他想通过添加方法等来扩展 Coordinates 的功能。如果他关心它不是引用类型,他仍然可以选择将 Coordinate 设为结构体。 - Tobias Tengler
3
不能修改它实际上可能是一种可取的特性。对于像坐标这样的东西,不允许更改是有意义的。它应该是不可变的。就像一个数字本身是不可变的一样。你不能把一个字面上的整数改成另一个数字,而是要用另一个数字代替它。我同意使用一个具有只读属性的结构体(或者也许是类)可能是有用的,但很可能不是因为可以潜在地被改变。 - Matt Burland
当然,你的观点是正确的。但由于原帖作者没有给出任何线索表明他想用这个做什么,整个问题仍然是个谜,我只回答了他关于语法的问题,并决定添加一些内容以向他展示,不使用元组也可以完成他想要的操作。 - Tobias Tengler
ValueTuple<...> 不是不可变的。 - Lasse V. Karlsen
关于不提供任何线索,他说他想避免在各个地方键入(int x, int y),而是使用一个名称来代替。这也是一个完全合法的请求,但如果你足够关心你的元组和匿名对象,认为它们应该有一个名称来标识它们,那么就使用一个适当命名的类型(就像这个答案提供的那样)。 - Lasse V. Karlsen

4

需要注意的两点:

  1. using 指令需要已知的命名空间或类型。
  2. 当元组声明为 (int x, int y) t = ... 时,您只有编译器命令而不是类型。

如果您将变量声明为元组,编译器将生成类似以下的内容。

[System.Runtime.CompilerServices.TupleElementNames(new string[] {"x", "y"})]
System.ValueTuple<int, int> myVar = ...

我们在这里讨论的是语法糖,它使得使用元组更加容易,并且在设计时可用命名项以生成编译时的实际类型。但某些指令等需要已知类型。因此,您可能会遇到导入不存在类型的问题。
请参阅此文章

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接