简体   繁体   English

C#6.0中的Monadic null检查

[英]Monadic null checking in C# 6.0

I stumbled across an interesting site, where some of the new (proposed) features of C# 6.0 are addressed. 我偶然发现了一个有趣的网站,其中解决了C#6.0的一些新的(提议的)功能。 You may read it here: Probable C# 6.0 features . 您可以在这里阅读: 可能的C#6.0功能

What I find particular interesting is the monadic null checking (also known as the null-propagation operator ?. ). 我觉得特别有趣的是monadic null检查(也称为null-propagation操作符 )。 According to the site, the following statement 根据网站,以下声明

var bestValue = points?.FirstOrDefault()?.X ?? -1;

contains the monadic null check, which is currently implemented with this piece of code: 包含monadic null检查,目前使用这段代码实现:

if (points != null) 
{
  var next = points.FirstOrDefault();
  if (next != null && next.X != null) return next.X;
}   
return -1;

My first glance was, hey, what the heck is written here? 我的第一眼就是,嘿,这里写的是什么? But after looking at the 'old' code, I am starting to like it. 但在查看“旧”代码后,我开始喜欢它了。

However, I am also starting to get some questions, which I'd like to ask. 但是,我也开始提出一些问题,我想问一下。

  • I assume that this null-propagating operator is thread safe. 我假设这个null传播的运算符是线程安全的。 But how is that actually performed? 但这实际上是如何进行的? Will race conditions be removed or are they persisting? 种族条件会被删除还是会持续存在?
  • How would this operator handle generic types? 该运算符如何处理泛型类型? Moreover, how would it deal with unconstrained generic types? 而且,它如何处理无约束的泛型类型? For example, consider 例如,考虑一下

     var resultAfterNullCheck = x?.Y; 

    If the type Y here is instantiated with reference types, non-nullable value types and nullable value types, there would be nothing reasonable to do (as I cannot think of what to do, as I simply do not know what to do). 如果这里的类型Y用引用类型,非可空值类型和可空值类型实例化,那么就没有任何合理的做法(因为我不知道该怎么做,因为我根本不知道该怎么做)。 So is there a default that will be returned? 那么是否会返回默认值? Or will it throw an error? 或者它会抛出错误?

  • When looking at the example the site provides (and which I copied above) I assume that one of the main benefits of the null-propagation operator will be that it will evaluate the statement only once. 在查看站点提供的示例(以及我在上面复制的示例)时,我假设null-propagation运算符的一个主要好处是它只会评估语句一次。 However (perhaps due to my lack of knowledge of CLR), I am quite curious on how it could be performed. 然而(也许是由于我对CLR的了解不足),我很好奇它是如何进行的。
    As to me, the first evaluation (if points equals null) should trigger the extension method FirstOrDefault() to trigger when points isn't null, followed by the evalation of the returned type to be null or not, if not, X will be returned. 对我来说,第一个评估(如果points等于null)应该触发扩展方法FirstOrDefault()在points不为null时触发,然后将返回类型的evalation设置为null或者不是,否则,X将是回来。 So these are in fact three evaluations combined to one? 那么这些实际上是三个评估合二为一? Or am I understanding it incorrectly? 或者我不正确地理解它? Will this affect speed of execution? 这会影响执行速度吗?

In other words, what will be faster, the old way of performing null checks, or this new lovely operator? 换句话说,什么会更快,执行空检查的旧方法,或这个新的可爱运算符? I will try to examine this by performing some research as soon as the download of Visual Studio 2015 is finished... But that requires a bit of patience... 我将在Visual Studio 2015下载完成后立即通过执行一些研究来检查这一点...但这需要一点耐心......

Are there any thoughts on this new operator type? 对这种新的操作员类型有什么想法吗? Is it really still a proposed one, or can we really expect to work with this new monadic null check? 它真的还是一个提议的,或者我们真的可以期望使用这个新的monadic null检查吗?

EDIT 编辑
As Matthew Watson provided a nice MSDN article discussing this (and more) topic(s), I was curious if it mentioned my earlier question regarding unconstrained generics and how this operator deals with that. 正如Matthew Watson提供了一篇很好的MSDN讨论这个(以及更多)主题的文章 ,我很好奇它是否提到了我之前关于无约束泛型的问题以及该运算符如何处理它。 Unfortunately, I haven't found an answer yet. 不幸的是,我还没有找到答案。 While I will suppose that the programmer should try to prevent the usage of unconstraint generics, I can still imagine that this is sometimes not feasible. 虽然我认为程序员应该试图阻止使用无约束泛型,但我仍然可以想象这有时是不可行的。 If that is the case, will a redesign be really necessary? 如果是这样的话,重新设计是否真的有必要?

You are way overthinking this. 你是在暗示这个。 One by one, your questions: 你的问题一个接一个:

  1. Why would you assume it's thread safe? 你为什么认为它的线程安全? Calling a member function isn't. 调用成员函数不是。 This is nothing but calling a member function with a pre-check for nulls, so you only get as much thread safety as the original function guarantees. 这只是通过预检查空值来调用成员函数,因此您只能获得与原始函数保证一样多的线程安全性。

  2. If your generic type allows null comparison (which is what this operator will use behind the scenes), then code will be emitted. 如果您的泛型类型允许空值比较(这是此操作符将在幕后使用),则将发出代码。 If not you'll get a compile error (for example if you require the type to be a value type). 如果不是,您将收到编译错误(例如,如果您要求类型为值类型)。 That covers all cases! 这涵盖了所有情况!

  3. It is called once -- per operator, just like the normal . 它被称为每个操作符,就像正常一样. operator. 运营商。 If you say Abc it's still going to be two levels of indirection, and using this new operator is nothing different, it just checks for nulls too. 如果你说Abc它仍然是两个级别的间接,并且使用这个新的运算符没什么不同,它只是检查空值。

The real benefits of ?. 真正的好处?. are that it's semantic (you can tell at a glance what your code is trying to do) and short circuiting (makes code a lot shorter than nested if s). 是它的语义(你可以一目了然地告诉你的代码试图做什么)和短路(使代码比嵌套if短得多)。 You aren't going to replace every . 你不会取代每一个. in your old code with ?. 在您的旧代码中?. , in fact you'll probably rarely use it. 事实上你可能很少使用它。 But there are cases where it's going to be useful, like in Linq expressions following ...OrDefault() operations, or calling events. 但有些情况下它会很有用,比如在Linq表达式中跟随...OrDefault()操作或调用事件。

To partially answer your first question, according to John Skeet on his blog , the null conditional operator ?. 根据John Skeet在他的博客中 ,部分回答你的第一个问题,空条件运算符?. (= null propagation operator) is thread safe. (= null传播运算符)是线程安全的。

You can find everything about planned features in Roslyn project discussion. 您可以在Roslyn项目讨论中找到有关计划功能的所有信息。 You can also try new features with console application using Roslyn like nuget-package (that means it works with Visual Studio 2013 <) 你也可以尝试使用Roslyn的控制台应用程序的新功能,如nuget-package(这意味着它适用于Visual Studio 2013 <)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM