gpt4 book ai didi

c# - DRY (Don't Repeat Yourself) 和作业

转载 作者:太空宇宙 更新时间:2023-11-03 18:02:26 25 4
gpt4 key购买 nike

我想我忘记了一些明显的东西,但我似乎无法找到一种方法来分配一个值,如果它验证一个条件保持尽可能干燥......一些代码来解释我的意思......

a = (b > 1) ? b : c;

甚至 a = (a > 1) ? a : b;

所以当然这没什么大不了的,但如果 a 被方法调用替换(可能是 yield return 那里)或其他什么,我将不得不调用它两次......

我唯一看到的是将它存放在一个变量中,然后就像上面的代码一样...

有更好的主意吗?

编辑以便更好地理解:假设我正在 xml 文件中搜索一个值,使用空检查 (?. ?[]) 等,例如

string store_no = myXmlNode.SelectSingleNode("aChildNode")?.SelectSingleNode("myNode")?.Attributes?["store_no]?.Value;

所以在这里我将其存储在一个变量中,以便稍后测试它的值。如果我想检查一个特定的 store_no !我必须做类似的事情

store_no = (store_no=="STORE23")? store_no : "unknown";

...是的,不确定这个例子是否足够明确,但想法就在这里;我可能不想将数据存储在变量中(例如,巨大的数据 block )有没有办法获得相同的结果?

最佳答案

I think I'm forgetting something evident but I can't seem to find a way to assign a value if it validates a condition remaining as DRY as possible

让我们首先消除您对一个常见误解的误解。

这完全是对 DRY 含义的错误陈述。如果您有 Customer对象,你有一个 Address对象和 Customer有字段 BillingCityBillingPostalCodeHomeCity依此类推,那么您的代码就不是 DRY,因为相同的信息在两个地方被冗余表示。您应该重新设计代码,以便 Customer收藏了 Address对象。

现在,避免在整个节目中剪切和粘贴重复代码确实是个好主意,但 DRY 是关于中型到大型 代码的设计。 DRY 绝对不意味着您的代码不应该在同一个表达式中两次使用同一个变量!

既然我们已经解决了这个问题,让我们看看您对语言的评论。

我们经常处于“表达式上下文”中的情况——也就是说,一个长的、可能是流利风格的表达式,我们希望避免做多余的工作。例如,我们可能有:

x = M() > 0 ? M() : 0;

也许调用 M()两次很昂贵,或者它不是幂等的。任何。没关系。重点是,我们不想调用它两次。

令人恼火的是,我们必须退出表达式上下文并进入语句上下文:

var m = M();
x = m > 0 ? m : 0;

这当然是合法的,但是有点烦人。此外,在某些情况下它可能会很棘手:

N(P() ?? (M() > 0 ? M() : 0));

现在我们该怎么办?假设我们只想调用 M(),没有明显的方法可以在不手写的情况下保留语义。如果P()为空。

var t = default(T);
var p = P();
if (p == null) {
var m = M();
t = m > 0 ? m : 0;
} else {
t = p.Value;
}
N(t);

恶心。天哪,这太可怕了。

其他语言通过引入 let 解决了这个问题表达式。我们真正想要的是能够在表达式中间引入一个新的局部变量。常见的语法是 let ID = EXPRESSION in EXPRESSIONID成为具有特定含义但仅在 in 范围内的只读变量:

N(P() ?? (let m = M() in m > 0 ? m : 0));

请注意,C# 确实 支持 let表达式,但仅在查询理解中。如果它在语言中更普遍地支持它,那就太好了。

多年来有很多建议添加let这些年来,表达式,或者它们更一般的形式,排序表达式,进入 C#。有关示例,请参阅 github roslyn 问题跟踪器。也许这会进入 C# 8;如果需要,请参加论坛。

那么在此期间您可以做什么?

事实证明,C# 中 let 表达式。 let x = y in z是一种很好的写法 (((Func<X, Z>)(x=>z))(y)) .所以你可以这样写:

N(P() ?? (((Func<int, int>)(m => m > 0 ? m : 0))(M())));

但这看起来几乎一样可怕。那是一个不可读的困惑。

问题是 lambda。这样会更好:

Func<int, int> f = m => m > 0 ? m : 0;
...
N(P() ?? f(M()));

但这有点不透明。我们如何进一步改进这一点?

我们可以使它成为一个本地函数,但更好的是,我们可以使它成为一个扩展方法并进行流畅的编程:

public static int NotNegative(this int x) => x > 0 ? x : 0;
...
N( P() ?? M().NotNegative());

完成。这只评估 M()一次,但是 super 奖励,它更容易阅读,因为现在程序文本代表正在对其执行的操作,而不是程序文本是一系列难以阅读的标点符号。

小的流利式扩展方法可以使您的代码更易于阅读。养成使用它们的习惯。

关于c# - DRY (Don't Repeat Yourself) 和作业,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50529952/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com