我开发的程序的功能之一涉及更改外部世界(例如修改文件),然后启动一个进程,等待其完成,然后撤消最初所做的更改。
这些更改可能会以不可预见的方式失败,在这种情况下,我们会中止一切并仅撤消已完成的操作。有一些更改需要进行。这会产生以下类型的代码:
DoChange1();
try {
DoChange2();
try {
DoChange3();
try {
[...]
}
finally {
UndoChange3();
}
finally {
UndoChange2();
}
finally {
UndoChange1();
}
Run Code Online (Sandbox Code Playgroud)
这太丑了。这嵌套在每个更改中,并且撤消更改的代码与应用该更改的代码以相反的顺序相距甚远 - 非常类似于将组操作应用于使用 完成的语言中的结构func(structure, lambda),而不是 LINQ 风格。
即使以函数调用的方式组织,我也更愿意能够做这样的事情:
DoChange1();
finally_onwards {
UndoChange1();
}
DoChange2();
finally_onwards {
UndoChange2();
}
DoChange3();
finally_onwards {
UndoChange3();
}
[...]
Run Code Online (Sandbox Code Playgroud)
一旦遇到finally,它就会变得活跃,并在作用域退出时以遇到的相反顺序调用。
遗憾的是,这不是 C# 构造 - 在正确撤消更改的同时,防止 try-finally 嵌套到无穷大的好解决方案是什么?
请注意,应始终撤消更改。X 的更改会影响 [...] 的进行,但之后应始终将其恢复。
出于改进目的,我试图使用专门的流来转置列表列表。
我的意思是,我有一个双打列表,其中包含例如
1 2 3 4
5 6 7 8
Run Code Online (Sandbox Code Playgroud)
我想获得一个包含双打列表的列表
1 5
2 6
3 7
4 8
Run Code Online (Sandbox Code Playgroud)
以下堆栈溢出问题提供了一种迭代方式:How to transpose List<List>?
到目前为止,我只想到了丑陋的解决方案,例如用包含列表中的值和索引的自定义对象替换 Double,使用 flatMap 展平,使用 groupBy 和我保存的索引再次构建它,然后返回到 Doubles .
如果您知道任何干净的方式,请告诉我。谢谢。
我正在学习 C# 并试图处理涌入的“a可能是null”警告。
我想知道,由于当某些内容为空时,通过从函数返回或抛出异常而出错是一种常见的情况,C# 是否有某种针对这种情况的语法糖?
我的想法的示例:(int a = obtainA() ??? { Console.WriteLine("Fatal error;") return };这不是真正的代码)
我了解??和??=运算符,但它们似乎没有多大帮助,而且我还没有找到更好的。
如果不是,我们最接近模仿的是什么?难道没有比写下面更好的方法了吗?
int? nullableA = obtainA();
int a;
if (nullableA.HasValue) {
a = nullableA.Value;
}
else {
Console.WriteLine("Fatal error");
return;
}
/* use a, or skip defining a and trust the static analyzer to notice nullableA is not null */
Run Code Online (Sandbox Code Playgroud)