6

我希望在 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[].

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

4

3 回答 3

4

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

float x, y, z = 0.1f;

这声明了三个变量xy并被初始化为. 您问题中提出的语法的差异充其量是微妙的。zz0.1

于 2013-09-10T12:36:20.680 回答
4

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

var x, y, z = rgb;

所以不管rgb是什么,只有z 被分配给它。如果您更改此行为,则绝对不清楚该行发生了什么:

  • 赋值给所有变量
  • 只分配给最后一个

如果你不在这里做出明确的决定,它会根据赋值运算符右侧的类型导致不同的行为:一种情况是声明和赋值做默认值,另一种情况是声明和赋值给特定值。

于 2013-09-10T12:37:20.957 回答
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 };

在这里,我们谈论 a 的事实List<int>非常清楚:-)

即使是有点“特殊”的数组初始值设定项,也不是隐含的……

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

都是有效的,但我们所说的数组的事实总是明确的(总是有 a []

var myVar = { 1, 2, 3 };

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

于 2013-09-10T13:29:14.747 回答