Home Random Page


CATEGORIES:

BiologyChemistryConstructionCultureEcologyEconomyElectronicsFinanceGeographyHistoryInformaticsLawMathematicsMechanicsMedicineOtherPedagogyPhilosophyPhysicsPolicyPsychologySociologySportTourism






Nbsp;   C#’s Support for Nullable Value Types

Notice in the code that C# allows you to use fairly simple syntax to initialize the two Nullable<Int32> variables, x and y. In fact, the C# team wants to integrate nullable value types into the C# language, making them first-class citizens. To that end, C# offers a cleaner syntax for working with nullable value types. C# allows the code to declare and initialize the x and y variables to be written using question mark notation.

 

Int32? x = 5; Int32? y = null;

 

In C#, Int32? is a synonym notation for Nullable<Int32>. But C# takes this further. C# allows you to perform conversions and casts on nullable instances. And C# also supports applying operators to nullable instances. The following code shows examples of these.

 

private static void ConversionsAndCasting() {

// Implicit conversion from non­nullable Int32 to Nullable<Int32> Int32? a = 5;

 

// Implicit conversion from 'null' to Nullable<Int32>

Int32? b = null; // Same as "Int32? b = new Int32?();" which sets HasValue to false

 

// Explicit conversion from Nullable<Int32> to non­nullable Int32 Int32 c = (Int32) a;

 

// Casting between nullable primitive types

Double? d = 5; // Int32­>Double? (d is 5.0 as a double) Double? e = b; // Int32?­>Double? (e is null)

}


C# also allows you to apply operators to nullable instances. The following code shows examples of this.

 

private static void Operators() { Int32? a = 5;

Int32? b = null;

 

// Unary operators (+ ++ ­ ­­ ! ~) a++; // a = 6

b = ­b; // b = null

 

// Binary operators (+ ­ * / % & | ^ << >>) a = a + 3; // a = 9

b = b * 3; // b = null;

 

// Equality operators (== !=)

if (a == null) { /* no */ } else { /* yes */ } if (b == null) { /* yes */ } else { /* no */ } if (a != b) { /* yes */ } else { /* no */ }

 

// Comparison operators (<> <= >=)

if (a < b) { /* no */ } else { /* yes */ }

}

 

Here is how C# interprets the operators:

 

Unary operators (+, ++, -, --, ! , ~)If the operand is null, the result is null.

Binary operators (+, -, *, /, %, &, |, ^, <<, >>)If either operand is null, the result is null. However, an exception is made when the & and | operators are operating on Boolean? op- erands, so that the behavior of these two operators gives the same behavior as demonstrated by SQL’s three-valued logic. For these two operators, if neither operand is null, the operator performs as expected, and if both operands are null, the result is null. The special behavior comes into play when just one of the operands is null. The following table lists the results produced by these two operators for all combinations of true, false, and null.

 

Operand1→Operand2↓ true false null
True & = true | = true & = false | = true & = null | = true
False & = false | = true & = false | = false & = false | = null
Null & = null | = true & = false | = null & = null | = null

Equality operators (==, !=)If both operands are null, they are equal. If one operand is null, they are not equal. If neither operand is null, compare the values to determine if they are equal.



Relational operators (<, >, <=, >=)If either operand is null, the result is false. If neither operand is null, compare the values.


You should be aware that manipulating nullable instances does generate a lot of code. For example, see the following method.

 

private static Int32? NullableCodeSize(Int32? a, Int32? b) { return a + b;

}

 

When I compile this method, there is quite a bit of resulting Intermediate Language (IL) code, which also makes performing operations on nullable types slower than performing the same opera- tion on non-nullable types. Here is the C# equivalent of the compiler-produced IL code.

 

private static Nullable<Int32> NullableCodeSize(Nullable<Int32> a, Nullable<Int32> b) {

 

Nullable<Int32> nullable1 = a; Nullable<Int32> nullable2 = b;

if (!(nullable1.HasValue & nullable2.HasValue)) { return new Nullable<Int32>();

}

return new Nullable<Int32>(nullable1.GetValueOrDefault() + nullable2.GetValueOrDefault());

}

 

Finally, let me point out that you can define your own value types that overload the various op- erators previously mentioned. I discuss how to do this in the “Operator Overload Methods” section in Chapter 8, “Methods.” If you then use a nullable instance of your own value type, the compiler does the right thing and invokes your overloaded operator. For example, suppose that you have a Point value type that defines overloads for the == and != operators as follows.

 

using System;

 

internal struct Point { private Int32 m_x, m_y;

public Point(Int32 x, Int32 y) { m_x = x; m_y = y; }

 

public static Boolean operator==(Point p1, Point p2) { return (p1.m_x == p2.m_x) && (p1.m_y == p2.m_y);

}

 

public static Boolean operator!=(Point p1, Point p2) { return !(p1 == p2);

}

}

 

At this point, you can use nullable instances of the Point type and the compiler will invoke your overloaded operators.

 

internal static class Program { public static void Main() {

Point? p1 = new Point(1, 1); Point? p2 = new Point(2, 2);

 

Console.WriteLine("Are points equal? " + (p1 == p2).ToString()); Console.WriteLine("Are points not equal? " + (p1 != p2).ToString());

}

}


When I build and run the preceding code, I get the following output.

 

Are points equal? False Are points not equal? True

 


Date: 2016-03-03; view: 726


<== previous page | next page ==>
Nullable Value Types | Nbsp;   The CLR Has Special Support for Nullable Value Types
doclecture.net - lectures - 2014-2024 year. Copyright infringement or personal data (0.008 sec.)