C# 检查属性的属性是否为 null 的优雅方法
在 C# 中,假设您想要从本示例中的 PropertyC
以及 ObjectA
、PropertyA
和 PropertyB
中获取值> 都可以为空。
ObjectA.PropertyA.PropertyB.PropertyC
如何用最少的代码安全地获取PropertyC
?
现在我会检查:
if(ObjectA != null && ObjectA.PropertyA !=null && ObjectA.PropertyA.PropertyB != null)
{
// safely pull off the value
int value = objectA.PropertyA.PropertyB.PropertyC;
}
做一些更像这样的事情(伪代码)会很好。
int value = ObjectA.PropertyA.PropertyB ? ObjectA.PropertyA.PropertyB : defaultVal;
空合并运算符可能会进一步崩溃。
编辑 最初我说我的第二个例子就像js,但我将其更改为伪代码,因为它被正确指出它在js中不起作用。
In C#, say that you want to pull a value off of PropertyC
in this example and ObjectA
, PropertyA
and PropertyB
can all be null.
ObjectA.PropertyA.PropertyB.PropertyC
How can I get PropertyC
safely with the least amount of code?
Right now I would check:
if(ObjectA != null && ObjectA.PropertyA !=null && ObjectA.PropertyA.PropertyB != null)
{
// safely pull off the value
int value = objectA.PropertyA.PropertyB.PropertyC;
}
It would be nice to do something more like this (pseudo-code).
int value = ObjectA.PropertyA.PropertyB ? ObjectA.PropertyA.PropertyB : defaultVal;
Possibly even further collapsed with a null-coalescing operator.
EDIT Originally I said my second example was like js, but I changed it to psuedo-code since it was correctly pointed out that it would not work in js.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(20)
在 C# 6 中,您可以使用 空条件运算符。所以原来的测试将是:
In C# 6 you can use the Null Conditional Operator. So the original test will be:
简短的扩展方法:
使用
这个简单的扩展方法以及更多内容,您可以在 http:// /devtalk.net/csharp/chained-null-checks-and-the-maybe-monad/
编辑:
使用它一段时间后,我认为此方法的正确名称应该是 IfNotNull()而不是原来的With()。
Short Extension Method:
Using
This simple extension method and much more you can find on http://devtalk.net/csharp/chained-null-checks-and-the-maybe-monad/
EDIT:
After using it for moment I think the proper name for this method should be IfNotNull() instead of original With().
你能在你的类中添加一个方法吗?如果没有,您是否考虑过使用扩展方法?您可以为您的对象类型创建一个名为
GetPropC()
的扩展方法。示例:
用法:
顺便说一句,这假设您使用的是 .NET 3 或更高版本。
Can you add a method to your class? If not, have you thought about using extension methods? You could create an extension method for your object type called
GetPropC()
.Example:
Usage:
By the way, this assumes you are using .NET 3 or higher.
你这样做的方式是正确的。
您可以使用类似于这里,使用 Linq 表达式:
但是手动检查每个属性要慢得多...
The way you're doing it is correct.
You could use a trick like the one described here, using Linq expressions :
But it's much slower that manually checking each property...
重构以遵守德墨忒尔定律
Refactor to observe the Law of Demeter
2014 年更新:C# 6 有一个新的运算符
?.
,称为“安全导航”或“空传播”阅读 http://blogs.msdn.com/b/jerrynixon/archive/2014/ 02/26/at-last-c-is-getting-sometimes- Called-the-safe-navigation-operator.aspx 了解详细信息
这长期以来一直是一个非常受欢迎的请求
https://visualstudio.uservoice.com /forums/121579-visual-studio/suggestions/3990187-add-operator-to-c-?tracking_code=594c10a522f8e9bc987ee4a5e2c0b38d
Update 2014: C# 6 has a new operator
?.
various called 'safe navigation' or 'null propagating'Read http://blogs.msdn.com/b/jerrynixon/archive/2014/02/26/at-last-c-is-getting-sometimes-called-the-safe-navigation-operator.aspx for details
This has long been a hugely popular request
https://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/3990187-add-operator-to-c-?tracking_code=594c10a522f8e9bc987ee4a5e2c0b38d
显然,您正在寻找 Nullable Monad:
则将
如果任何可为 null 的属性为 null, 返回
null
;否则为Value
的值。LINQ扩展方法:
You're obviously looking for the Nullable Monad:
becomes
This returns
null
, if any of the nullable properties are null; otherwise, the value ofValue
.LINQ extension methods:
假设您有类型的空值,一种方法是:
我是 C# 的忠实粉丝,但新 Java(1.7?)中的一个非常好的东西是 .?操作员:
Assuming you have empty values of types one approach would be this:
I'm a big fan of C# but a very nice thing in new Java (1.7?) is the .? operator:
我在新的 C# 6.0 中看到了一些东西,
这是通过使用“?”例如,不要检查
而不是使用
你,只需使用
我希望它对某人有帮助。
更新:
你现在可以这样做
I saw something in the new C# 6.0,
this is by using '?' instead of checking
for example instead of using
you simply use
I hope it helped somebody.
UPDATE:
You could do like this now
这段代码是“最少的代码量”,但不是最佳实践:
This code is "the least amount of code", but not the best practice:
当我需要像这样链接调用时,我依赖于我创建的辅助方法 TryGet():
在您的情况下,您将像这样使用它:
When I need to chain calls like that, I rely on a helper method I created, TryGet():
In your case, you would use it like so:
你可以这样做:
或者更好的是:
You could do this:
Or even better might be this:
我会使用与 Nullable 类型类似的模式以 PropertyA 类型(如果不是您的类型,则为扩展方法)编写您自己的方法。
I would write your own method in the type of PropertyA (or an extension method if it's not your type) using the similar pattern to the Nullable type.
你可以使用以下扩展,我认为它非常好:
它的使用方式如下:
you can use the following extension and I think it is really good:
And it is used like this:
一旦你克服了 lambda 的繁琐,这种方法就相当简单了:
使用方式可能如下所示:
This approach is fairly straight-forward once you get over the lambda gobbly-gook:
With usage that might look like:
刚刚偶然发现了这篇文章。
不久前,我在 Visual Studio Connect 上提出了关于添加新的
???
运算符的建议。http ://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/4104392-add-as-an-recursive-null-reference-check-opera
这需要框架团队做一些工作,但是不需要改变语言,只需执行一些编译器魔法即可。这个想法是编译器应该将此代码(不允许 atm 的语法)更改
为此代码
对于 null 检查,这可能看起来像
Just stumbled accross this post.
Some time ago I made a suggestion on Visual Studio Connect about adding a new
???
operator.http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/4104392-add-as-an-recursive-null-reference-check-opera
This would require some work from the framework team but don't need to alter the language but just do some compiler magic. The idea was that the compiler should change this code (syntax not allowed atm)
into this code
For null check this could look like
我编写了一个接受默认值的方法,以下是如何使用它:
这是代码:
I wrote a method that accepts a default value, here is how to use it:
Here is the code:
这是不可能的。
如果
ObjectA
由于 null 取消引用而为 null,则ObjectA.PropertyA.PropertyB
将失败,这是一个错误。if(ObjectA != null && ObjectA.PropertyA
... 由于短路而起作用,即ObjectA.PropertyA
如果ObjectA< 则永远不会被检查/code> 是
null
。您建议的第一种方法是最好的,也是最明确的,您可以尝试重新设计,而不必依赖这么多空值。
It is not possible.
ObjectA.PropertyA.PropertyB
will fail ifObjectA
is null due to null dereferencing, which is an error.if(ObjectA != null && ObjectA.PropertyA
... works due to short circuiting, ieObjectA.PropertyA
will never be checked ifObjectA
isnull
.The first way you propose is the best and most clear with intent. If anything you could try to redesign without having to rely on so many nulls.
教师 教师 = new Teacher();
老师.name = 老师.name == null ?默认值:教师.姓名;
Teacher teacher = new Teacher();
teacher.name = teacher.name == null ? defaultvalue : teacher.name;
??
(空合并运算符)意味着如果第一个参数为null
,则返回第二个参数。The
??
(null-coalescing operator) means if the first argument isnull
, return the second one instead.