有什么理由我们不能在元组周围有一些语法糖吗?

时间:2013-09-10 12:32:12

标签: c# tuples syntactic-sugar

我希望在C#中看到的是关于元组的更好的语法,例如。

var rgb = (1.0f, 1.0f, 1.0f);
// Inferred to be Tuple<float, float, float>
// Translated to var rgb = Tuple.Create(1.0f, 1.0f, 1.0f)

并且

var x, y, z = rgb;

// Translated to:
//    float x = rgb.Item1;
//    float y = rgb.Item2;
//    float z = rgb.Item3;

C#语言中是否有任何禁止此内容的内容,或者使其难以实现或不切实际?也许还有其他语言特征会与此直接冲突?

请注意,我不是在询问微软是否在微软雷达上,或者即使它与他们对C#的愿景一致,只是理论上它有明显的阻挡剂。

修改 以下是其他CLI语言的一些示例

// Nemerle - will use a tuple type from a language specific runtime library
def colour = (0.5f, 0.5f, 1.0f);
def (r, g, b) = colour;

// F# - Will use either a library type or `System.Tuple` depending on the framework version.
let colour = (0.5f, 0.5f, 1.0f)
let (r, g, b) = colour

// Boo - uses CLI array
def colour = (0.5, 0.5, 1.0)
def r, g, b = colour

// Cobra - uses CLI array
var colour = (0.5, 0.5, 1.0)
var r, g, b = colour

虽然使用数组似乎是一个很好的折衷方案,但在混合类型时它会变得有限。 let a, b = (1, "one") F#或Nemerle会给我们Tuple<int, string>。在Boo或Cobra中,这将给我们object[]

EDIT2 C#7中添加了对元组的语言支持 - https://www.kenneth-truyers.net/2016/01/20/new-features-in-c-sharp-7/

3 个答案:

答案 0 :(得分:3)

第二个是不可能的,因为它已经意味着其他东西:

float x, y, z = 0.1f;

这声明了三个变量xyz,其中z被初始化为0.1。你问题中提出的语法的差异充其量是微妙的。

答案 1 :(得分:3)

这显然是一个设计问题,因为在您的情况下,您只将值 分配给最后一个变量,其他两个假设指定类型的默认值。

var x, y, z = rgb;

因此无论rgb是什么, z被分配给它。如果你改变了这种行为,那么绝对不清楚该行的内容:

  • 分配给所有变量
  • 仅分配到最后一个

如果你不在这里做出明确的决定,它将导致基于赋值运算符 right 侧的类型的不同行为:在一种情况下,它将是声明和赋值做默认值,在另一个案例中声明和赋予特定价值。

答案 2 :(得分:1)

第二种语法已被Tigran和Hilgarth证明是不可行的。

让我们看第一句语法:

var rgb = (1.0f, 1.0f, 1.0f);

如果您不想使用Tuple类会发生什么情况,因为相反,您希望使用MyTuple类(可能具有IEnumerable<object>的优势,有用!)?显然,语法无济于事。您必须将MyTuple类放在某个地方......

MyTuple<float, float, float> rgb = (1.0f, 1.0f, 1.0f);

var rgb = new MyTuple<float, float, float>(1.0f, 1.0f, 1.0f);

现在,这种新的速记语法的优势不再存在,因为在某处您必须放置MyTuple<float, float, float>

请注意,没有任何单一的集合初始化程序只是“自动发现”所有内容。

var myVar = new List<int> { 1, 2, 3 };

这里我们谈到List<int>的事实很清楚: - )

即使数组初始化程序,有点“特殊”,也不是隐含的......

int[] myVar = { 1, 2, 3 };
var myVar = new[] { 1, 2, 3 };
var myVar = new int[] { 1, 2, 3 };

都是有效的,但是我们所说的数组总是明确的(总有一个[]

var myVar = { 1, 2, 3 };

无效:-)并且数组具有作为原始构造的“优势”(数组直接由IL语言支持,而所有其他集合都构建在其他.NET库之上和/或数组)