Talking about c#6.0 improvement from Nullobject

Source: Internet
Author: User

Objective

This article is to talk about the null check problem we often do, from a simple null value to check any where, to the design pattern of the nullobjectpattern, and then to c#6.0 "may" provide the syntax, let's experience a language development on the "continuous improvement", lets ' s go~

What is a null reference exception

As a code-tapping farmer, it seems that no one has ever encountered the problem of NullReferenceException, and sometimes when a method internally invokes a property, Method (delegate), we control the performance of these properties in the "outer" (except in some cases with the REF keyword) , so we have to judge the property in the inside of the method, whether the delegate method is null to avoid possible, incorrect use of the null reference exception, so that when we know that if the object is null, we will achieve in line with our "expected" behavior.

Resolve NULL Reference Exception---Check any Where

It's easy, I just need to check if it's null. Yes, this is very simple and semantically clear, but when you want to double-check an object entity 100 million times, there are 10,000 code snippets in your code:

         Public void Check ()        {            ifnull)            {                true;            }         }

Can you tolerate such behavior?

If (OK)

Continue;

Else

Close;

Applying Nullobject Design Patterns

Nullobjectpattern from Forth by Gamma (design mode 4-person group), the core content is: to provide a null proxy for a given object, the null agent provides a way to do nothing in the implementation.

Now let's look at the C # implementation on Wikipedia:

//Compile as Console application, requires C # 3.0 or higherusingSystem;usingSystem.Linq;namespaceMyextensionwithexample { Public Static classstringextensions { Public Static intSafegetlength ( This stringvalueornull) {             return(Valueornull??string. Empty).         Length; }    }     Public Static classProgram {//define some strings        Static ReadOnly string[] strings =New[] {"Mr X.","Katrien Duck",NULL,"Q" }; //Write The total length of the strings in the array         Public Static voidMain (string[] args) {            varquery = fromTextinchStringsSelectText. Safegetlength ();//no need to does any checks hereConsole.WriteLine (query.        Sum ()); //The output would be:18        }    }}

In the C # language, we implement a static extension method to unify the inspection method inside the methods, rather than writing them everywhere, the above example implements a Safegetlength extension method on the string class, which provides a method for all string types so that we " Code neat "on another step.

Let's look at a more common example---from StackOverflow

     Public Static class eventextensions    {        publicstaticvoid raise<t> (The Thisobject  sender, T args)            where  t:eventargs        {            ifnull)            {                evnt (sender, args);            }        }    }

Finally, to say a detail question, the above code all did not implement "thread safety", in Daniel Eric Lippert's article for thread safety has had a more exciting discussion, please poke here.

The improved code adds a temporary variable inside the method, as a copy of the inside of the method, for thread safety, and if you have questions, refer to the chapter on the stack of the method's internal variables in my C # heap vs stack.

     Public class SomeClass    {        publicevent eventhandler<eventargs> myevent;         Private void dosomething ()        {            var tmp = myevent;            Myevent.raise (this, eventargs.empty);        }    }

More "tidal" way to-c#6.0 grammar

Mark Michaelis from MSDN Magazine (author of the C # Nature theory) gave us an introduction to the new improvements that c#6.0 might bring to the language, including improvements to the null conditional operator.

c#6.0 More references:

Part one:https://msdn.microsoft.com/zh-cn/magazine/dn683793.aspx

Part two:https://msdn.microsoft.com/zh-cn/magazine/dn802602.aspx

Even beginners of. NET development may be familiar with NullReferenceException. One exception is the fact that a Bug is almost always pointed out because the developer did not make sufficient null checks before invoking the members of the (null) object. Take a look at the following example:

 public  static  string  Truncate (string  value, int   length) { string  result = value;  if  (value! = null ) //  Skip empty string check for elucidation   = value. Substring (0   return   result;}  

This method throws a NullReferenceException if no null check is performed. Although this is simple, the process of checking whether a string parameter is null is a little cumbersome. Often, considering the frequency of comparisons, the tedious approach may not be necessary. C # 6.0 includes a new null-conditional operator that can help you write these checks more easily:

 public  static  string  Truncate (string  value, int   length) { return  value?. Substring (0   public  void   Truncate_withnull_returnsnull () {assert.areequal  < string  > (null , Truncate (null , 42  );}  

Depending on what is demonstrated by the Truncate_withnull_returnsnull method, if the value of the object is actually NULL, the null condition operator returns NULL. This brings up the question of what happens to the null conditional operator when it appears in the call chain? As shown in the following example:

 Public Static stringAdjustwidth (stringValueintlength) {  returnValue?. Substring (0, Math.min (value. length, length)). PadRight (length);} [TestMethod] Public voidadjustwidth_giveninigomontoya42_returnsinigomontoyaextended () {assert.areequal<int> ( the, Adjustwidth ("Inigo Montoya", the). Length);}

Although Substring is called by the null condition operator, and null value?. Substring seems to return null, but the language behaves as you think. This simplifies the process of calling PadRight and immediately returns NULL, thus avoiding programming errors that can cause NullReferenceException to occur. This concept is called "Null propagation".

The null condition operator makes a null check based on the condition, and then calls the target method and all other methods in the chain. This will likely produce a surprising result, for example, text?. The result in the Length.gettype statement.

If the null condition operator returns NULL when the call target is null, then what is the final data type when the call returns a member of the value type (assuming the value type cannot be null)? For example, from value?. The data type returned by Length cannot be just int. The answer is of course: a nullable type (int?). )。 In fact, attempting to assign only the result to int will cause a compilation error:

int // Compile error:cannot implicitly convert type ' int? ' to ' int '

Null conditions have two syntactic forms. First, the question mark precedes the dot operator (?.). Second, use the question mark and index operators together. For example, given a collection (not an explicit null check before indexing to the collection), you can do this using the null condition operator:

 public  static  ienumerable<t > Getvaluetypeitems<t> <T> collection, params  int  [] indexes)  where  T: struct  { foreach  (int  index in   indexes) {T ? Item = collection?    [index];  if  (item! = null ) yield  return   (T) item; }}

This example uses an operator? [...] The null conditional index form, which causes the collection to be indexed only if the collection is not null. By this form of the null condition operator, T? Item = collection? The [index] statement behaves as follows:

T? Item = (Collection! = null)? Collection[index]: null.

Note that the null condition operator can only retrieve items, and no items will be assigned. If a null collection is given, what does this mean?

Note Use for reference types? [...] Implicit ambiguity of the time. Since the reference type can be null, is it null for the collection, or if the element itself is actually null, from? [...] The null result of the operator is ambiguous.

A very useful application of the Null condition operator solves a feature that C # has existed since C # 1.0, that is, to check for NULL before invoking the delegate. Let's take a look at the C # 2.0 code shown in the figure .

  Figure 1 Checking for Null before invoking a delegate

classtheremostat{Eventeventhandler<float>ontemperaturechanged; Private int_temperature;  Public intTemperature {Get    {      return_temperature; }    Set    {      //If There is any subscribers and then//notify them of changes in temperatureeventhandler<float> localonchanged =ontemperaturechanged; if(Localonchanged! =NULL) {_temperature=value; //Call subscribersLocalonchanged ( This, value); }    }  }}

By using the null condition operator, the entire set implementation process can be simplified to:

Ontemperaturechanged?. Invoke (This, value)

Now, you only need to call invoke with the null conditional operator as the prefix, no longer have to assign the delegate instance to a local variable for thread safety, or even explicitly check whether the value is null before invoking the delegate.

C # developers are interested in knowing whether this content has improved in the latest four releases. The answer is that the improvements were finally made. Only this feature can change the way a delegate is invoked.

Another common pattern that is prevalent with the null conditional operator is in conjunction with the coalesce operator. Instead of a null check on Linesofcode before calling Length, you can write the item count algorithm as follows:

list<string> Linesofcode = Parsesourcecodefile ("Program.cs"); return 0;

In this case, any empty collection (no items) and a null collection are normalized to return the same number. In summary, the null conditional operator implements the following functionality:

  1. If the operand is null, NULL is returned

  2. If the operand is null, simplify the other calls in the call chain

  3. Returns a nullable type (system.nullable<t>) if the target member returns a value type.

  4. Support delegate invocation in a thread-safe manner

  5. use as the member operator (?.) and index operator (? ...])

Sample code Download

Reference

Http://stackoverflow.com/questions/13629051/net-event-raising-and-nullobject-pattern---Thread-safe extension mechanism

Https://msdn.microsoft.com/zh-cn/magazine/dn802602.aspx---c#6.0 null conditional operator

Http://en.wikipedia.org/wiki/Null_Object_pattern---nullobjectpattern on wikipedia

Talking about c#6.0 improvement from Nullobject

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.