有没有办法将元组重建为兼容类?

时间:2017-07-14 10:51:17

标签: c# .net c#-7.0

给定一个元组(int,string)v和一个类C {int,string},在C#7中,实现C的Deconstruct(out int k,out string v)将允许ff。:

C c = new C();
(int k, string v) = c;

但反过来似乎没有支持,因此元组可以“重建”到兼容的类:

(int k, string v) vt = (1, "one");
C c = vt;

我认为如果C有一个“匹配”C的Deconstruct()参数的构造函数,它应该得到支持:

class C
{
    public C(int k, string v)
    ...
}

有可能吗?可用?计划?我似乎找不到任何关于它的东西。或者可能是“重构”的可重用代码/技巧?

3 个答案:

答案 0 :(得分:25)

当然可以。只需实现一个隐式运算符:

public static implicit operator C((int, string) t) 
    => new C(t.Item1, t.Item2);

不需要一些特殊的Reconstruct方法,因为该语言已经提供了实现所需行为的必要工具。

答案 1 :(得分:14)

之间有一个非常微妙的区别:

(int, string) x = c; // tuple assignment
(int a, string b) x = c; // tuple assignment with member aliases

(int a, string b) = c; // deconstruction

重要的是你的代码都不是,因此不会编译 - 但从上下文中可以清楚地看到你正在讨论解构语法,所以我假设是底层形式。 / p>

解构语法(在类似元组的表达式之后没有名称的 )实际上并不创建元组。实际上,它需要中的名称

(int a, string b) = c;

或:

var (a, b) = c;

这是一个元组,但它是方便的语法:

c.Deconstruct(out int a, out string b);

所以:在任何时候都不涉及元组(虽然奇怪的是System.ValueTuple引用仍然是必需的。)

反向操作 - 将多个变量传递给构造函数 - 是:常规构造函数。请注意,您无法将“类似于元组的内容”传递到任何地方,因为它没有名称 - 它不是本地

答案 2 :(得分:3)

已经有一种方法可以解构(即将一些对象分解为其组成元素)。它正在“构建”(即从组件中制作对象)。与c = new C(x, y);相反的最简单方法是c = new C(x, y);

通过省略/推断构造函数的类型,正在考虑将候选功能简化为c = new (x, y);new之类的语法。它被称为目标类型构造([1])。

如果您想提出其他一些构建方法,那么显示新功能的价值非常重要。 csharplang repo是讨论这些想法并了解社区和团队反馈的好地方。

可能会讨论删除(x, y, z) = (a, b);,但我认为这不是一个好主意。例如,在C中,编译器应该考虑从两个元素a和b构造类型Deconstruct,然后使用它可能在C上找到的三个元素调用JOB_NAME=my_job_name BUCKET_NAME=my_bucket_name OUTPUT_PATH=gs://$BUCKET_NAME/$JOB_NAME DATA_PATH=gs://$BUCKET_NAME/my_data_directory REGION=us-east1 gcloud ml-engine jobs submit training $JOB_NAME \ --job-dir $OUTPUT_PATH \ --runtime-version 1.2 \ --module-name trainer.task \ --package-path trainer/ \ --region $REGION \ -- \ --file-path "${DATA_PATH}/*" \ --num-epochs 10 方法?您可以看到如何将解构作为转换(可以链接并出现在代码中的许多位置)导致组合爆炸。

[1]:https://github.com/dotnet/csharplang/issues/100(该链接跟踪此候选功能,并链接到最新的LDM注释,由于未详细讨论语言功能,因此这些注释非常简洁)。