给定一个元组(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)
...
}
有可能吗?可用?计划?我似乎找不到任何关于它的东西。或者可能是“重构”的可重用代码/技巧?
答案 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注释,由于未详细讨论语言功能,因此这些注释非常简洁)。