空数组和 IEnumerable
上一个问题讨论了 IEnumerable 以及使用空集合而不是空值集合的约定。这是一个很好的做法,因为它消除了许多容易出错的空检查。
但答案并不能完全解决其中一种情况。很多时候我被迫处理空值,特别是当从外部方法返回数组时。一个例子:
(foreignObj.GetPeople() ?? Enumerable.Empty<Person>())
.Where(p => p.Name != "John")
.OrderBy(p => p.Name)
.Take(4);
我编写了一个辅助方法,它确实在一定程度上提高了可读性。
public class SafeEnumerable
{
public static IEnumerable<T> From<T>(T[] arr)
{
return arr ?? Enumerable.Empty<T>();
}
}
结果是:
SafeEnumerable.From(foreignObj.GetPeople())
.Where(p => p.Name != "John")
.OrderBy(p => p.Name)
.Take(4);
我不介意这一点,但我正在寻找更好的想法。看起来我正在添加一些本来就应该存在的东西。
A previous question discusses IEnumerable and the convention of using empty collections instead of null valued ones. It is a good practice as it does away with many mistake-prone null checks.
But the answers don't quite address one of the cases. Many times I'm forced to deal with null values, specifically when arrays are returned from foreign methods. An example:
(foreignObj.GetPeople() ?? Enumerable.Empty<Person>())
.Where(p => p.Name != "John")
.OrderBy(p => p.Name)
.Take(4);
I've written a helper method which does improve readability somewhat.
public class SafeEnumerable
{
public static IEnumerable<T> From<T>(T[] arr)
{
return arr ?? Enumerable.Empty<T>();
}
}
Resulting in:
SafeEnumerable.From(foreignObj.GetPeople())
.Where(p => p.Name != "John")
.OrderBy(p => p.Name)
.Take(4);
I don't mind this, but I'm looking for better ideas. It seems like I'm adding something that should be there already.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
问题定位于您获取集合的位置(
IEnumerable
)。如果您总是忙于检查集合的null
值,则应考虑修改源代码。例如:第一个方法如果在未找到用户时返回
null
则有意义,null
返回值意味着未找到。但在我看来,第二种方法在任何正常情况下都不应该返回null
。如果没有找到用户,则应返回一个空列表,而不是null
值,这意味着程序的某些内容不正确。在你的问题中给出的例子,我不相信如果没有找到txt
文件,directoryInfo.GetFiles("*.txt")
返回 null,相反它应该返回一个空集合。The problem locates where you got the collection(
IEnumerable<T>
). If you are always busy with checking fornull
values of a collection, you should consider to modify the source. For example:The first method makes sense if it returns a
null
when no user is found, anull
return value means not found. But the second method, in my opinion, should never return anull
in any normal circumstance. If no users found, an empty list should be returned, instead of anull
value, which means something of the program is incorrect. And the given example in your question, I don't believedirectoryInfo.GetFiles("*.txt")
returns null if notxt
file is found, instead it should return an empty collection.我为 IEnumerable 创建了一系列扩展方法,其中第一个是 EmptyIfNull
例如。
这允许我这样做,
然后我添加了“安全”扩展,这样我就可以使代码更短一些以便输入/更易于阅读,
例如
给予
I have created a series of extension methods for IEnumerable, the first of which being EmptyIfNull
eg.
this allows me to do
I have then added "Safe" extensions so I can make the code a little shorter to type/easier to read
e.g.
giving
如果您无法修改源代码以更正返回 null 的方法,那么您的方法就有意义。
您也许可以将其设为扩展方法,以便可以以更惯用的 LINQy 方式使用它:
If you can't modify the source to correct the method that returns null then your approach makes sense.
You could perhaps make it an extension method so that it can be used in a more idiomatic, LINQy way:
不幸的是,我不认为有任何内置的东西可以做到这一点。除非你重复一遍:
一个稍微“更好”的实现(以 C# 编译器为
yield return
sytnax 生成的示例),它稍微减少了内存浪费:Unfortunately I don't think that there is anything built-in for this. Unless you repeat yourself:
A slightly 'better' implementation (taking example from what the C# compiler generates for the
yield return
sytnax), which is marginally less wastefuly with memory: