如何替换字典的 IF 语句? (C#,Linq)
Posted
技术标签:
【中文标题】如何替换字典的 IF 语句? (C#,Linq)【英文标题】:How to replace IF statements for dictionary? (C#, Linq) 【发布时间】:2020-11-19 05:28:20 【问题描述】:我有一个 SampleObject 的相等比较器:
public bool Equals(SampleObject x, SampleObject y)
if (x == null)
return y == null;
if (y == null)
return false;
if (!string.Equals(x.SomeId, y.SomeId))
return false;
if (x.EventsList == null)
return y.EventsList == null;
if (y.EventsList == null)
return false;
return x.EventsList.OrderBy(e => e)
.SequenceEqual(y.EventsList.OrderBy(e => e));
我想知道是否有办法替换字典中的所有 IF 子句?
【问题讨论】:
不是答案,而是观察:当 x.EventsList 和 y.EventsList 都为空时,您将它们视为相等 - 但当 x 和 y 都为空时,您将它们视为不相等。你是故意的吗? @MatthewWatson:我不这么认为:如果 x 和 y 都为 null,则 if (x == null) return y == null 将返回 true。莱蒂没有改变问题,不是吗? 你确定是指字典吗?它的关键/价值是什么?或者你是否在使用某种机制,你有某种可枚举的规则集,而第一个返回的规则会终止规则的枚举? 旁注:请避免null
用于集合,例如EventList
;改用空的
@GWimpassinger Doh。 :) 当然你是对的。我需要增加我的字体大小...
【参考方案1】:
这是不可能的字典,但有一个列表。字典没有顺序,因此您不能保证您的检查以正确的顺序执行。我使用了一个元组列表,其中第一项是条件,第二项是返回值。您的代码如下:
public bool Equals(SampleObject x, SampleObject y)
var checks = new List<(Func<bool>,Func<bool>)>
(() => x == null, () => y == null),
(() => y == null, () => false),
(() => !string.Equals(x.SomeId, y.SomeId), () => false),
(() => x.EventsList == null, () => y.EventsList == null),
(() => y.EventsList == null, () => false)
;
foreach(var entry in checks)
if(entry.Item1.Invoke())
return entry.Item2.Invoke();
return x.EventsList.OrderBy(e => e)
.SequenceEqual(y.EventsList.OrderBy(e => e));
但我强烈建议保留您的原始版本,因为从我的角度来看,这种方法的可读性会大大降低。有时,一个经典的 if 语句序列比任何花哨的 LINQ 或其他任何东西都更合适。
【讨论】:
我会将其设置为正确答案,因为它确实提供了“调度”解决方案的选项。但我认为,正如@SomeBody 所建议的那样,我会尝试使用更简单的描述方式。【参考方案2】:好吧,我怀疑Dictionary
在这里是否有任何帮助,但是您可以将例程稍微简化为
public bool Equals(SampleObject x, SampleObject y)
if (ReferenceEquals(x, y))
return true;
else if (x == null || y == null)
return false;
// From now on, both x and y are not null
//TODO: to avoid such constructions, do not let collections be null, but empty
if (x.EventList == null || y.EventList == null)
return x.EventList == y.EventList;
// From now on, both x.EventList and y.EventList are not null
return string.Equals(x.SomeId, y.SomeId) &&
x.EventList.OrderBy(e => e).SequenceEquals(y.EventList.OrderBy(e => e));
【讨论】:
我喜欢这个!看起来很干净,而且不那么重复。【参考方案3】:我认为字典在这里没有任何帮助。您可以用一个简单的表达式替换所有 if 语句:
return
x == null && y == null ||
x != null && y != null &&
String.Equals(x.SomeId, y.SomeId) &&
(x.EventsList == null && y.EventsList == null ||
x.EventsList != null && y.EventsList != null &&
x.EventsList.OrderBy(e => e)
.SequenceEqual(y.EventsList.OrderBy(e => e));
请注意,由于 C# 的 short-circuit evaluation,在大多数情况下只需要对表达式进行部分计算。
【讨论】:
以上是关于如何替换字典的 IF 语句? (C#,Linq)的主要内容,如果未能解决你的问题,请参考以下文章