4.10. New Types

Now that the lowdown changes are out of the way, lets look at some of the new types in .NET 4.0 and modifications to existing classes and methods.

4.10.1. BigInteger

Working with really big numbers in .NET can get a bit strange. For example, try the following example (without advanced options such as overflow checking), and you might be surprised at the result you get:

int a = 2000000000;
Console.WriteLine(a * 2);
Console.ReadKey();

Surely the result is 4000000000? Running this code will give you the following answer:

−294967296

NOTE

VB.NET won't even let you compile the equivalent.

This issue occurs due to how this type of integer is represented in binary and the overflow that occurs. After the multiplication, the number gets bigger than this type can handle, so it actually becomes negative.

OK, not many applications will need to hold values of this magnitude. But for those that do, .NET 4.0 introduces the BigInteger class (in the System.Numerics namespace), which can hold really big numbers.

BigInteger is an immutable type with a default value of 0 with no upper or lower bounds. This upper value is subject to available memory, of course, and if it's exceeded, an out-of-memory exception will be thrown. But seriously, what are you holding? Even the US national debit isn't that big.

BigIntegers can be initialized in two main ways:

BigInteger bigIntFromDouble = new BigInteger(4564564564542332);
BigInteger assignedFromDouble = (BigInteger) 4564564564542332;

BigInteger has a number of useful (and self-explanatory) methods not found in other numeric types:

  • IsEven()

  • IsOne()

  • IsPowerOfTwo()

  • IsZero()

  • IsSign()

4.10.2. Lazy<T>

Lazy<T> allows you to easily add lazy initialization functionality to your variables. Lazy initialization saves allocating memory until the object is actually used. So, if you never end up accessing your object, you have avoided using the resources to allocate it. Additionally, you have spread out resource allocation through your application's life cycle, which is important for the responsiveness of UI-based applications.

Lazy<T> couldn't be easier to use:

Lazy<BigExpensiveObject> instance;

Lazy has implications for multithreaded scenarios. Some of the constructors for the Lazy type have an isThreadSafe parameter (see MSDN for more details of this: http://msdn.microsoft.com/en-us/library/dd997286%28VS.100%29.aspx).


4.10.3. Memory Mapped Files

A memory mapped file maps the contents of a file into memory, allowing you to work with it in a very efficient manner. Memory mapped files can also be used for interprocess communication, allowing you to share information between two applications:

Let's see how to use memory mapped files for interprocess communication:

  1. Create a new console application called Chapter4.MemoryMappedCreate.

  2. Add the following using statements:

    using System.IO;
    using System.IO.MemoryMappedFiles;

  3. Enter the following code in the Main() method:

    //Create a memory mapped file
    using (MemoryMappedFile MemoryMappedFile = MemoryMappedFile.CreateNew("test", 100))
    {
        MemoryMappedViewStream stream = MemoryMappedFile.CreateViewStream();
    
        using (BinaryWriter writer = new BinaryWriter(stream))
        {
            writer.Write("hello memory mapped file!");
        }
    
        Console.WriteLine("Press any key to close mapped file");
        Console.ReadKey();
    }

  4. Add another console application called Chapter4.MemoryMappedRead to the solution.

  5. Add the following using statements:

    using System.IO;
    using System.IO.MemoryMappedFiles;

  6. Enter the following code in the Main() method:

    //Read a memory mapped file
    using (MemoryMappedFile MemoryMappedFile = MemoryMappedFile.OpenExisting("test"))
    {
        using (MemoryMappedViewStream Stream = MemoryMappedFile.CreateViewStream())
        {
            BinaryReader reader = new BinaryReader(Stream);
            Console.WriteLine(reader.ReadString());
        }
    
        Console.ReadKey();
    }

  7. You have to run both projects to demonstrate memory mapped files. First, right-click the project Chapter4.MemoryMappedCreate and select Debug "Start new instance." A new memory mapped file will be created and a string written to it.

  8. Right-click the project Chapter4.MemoryMappedRead and select Debug "Start new instance." You should see the string hello memory mapped file! read and printed from the other project.

The other main use of memory mapped files is for working with very large files. For an example, please refer to this MSDN article: http://msdn.microsoft.com/en-us/library/system.io.memorymappedfiles.memorymappedfile(VS.100).aspx.

4.10.4. SortedSet<T>

Sorted set is a new type of collection in the System.Collections.Generic namespace that maintains the order of items as they are added. If a duplicate item is added to a sorted set, it will be ignored, and a value of false will be returned from SortedSet's Add() method.

The following example demonstrates creating a sorted list of integers with a couple of duplicates in it:

SortedSet<int> MySortedSet = new SortedSet<int> { 8, 2, 1, 5, 10, 5, 10, 8 };

4.10.5. ISet<T> Interface

.NET 4.0 introduces ISet<T>, a new interface utilized by SortedSet and HashSet, and surprisingly enough for implementing set classes.

4.10.6. Tuple

A tuple is a typed collection of fixed size. Tuples were introduced for interoperability with F# and IronPython, but can also make your code more concise.

Tuples are very easy to create:

Tuple<int, int, int, int, int> MultiplesOfTwo = Tuple.Create(2, 4, 6, 8, 10);

Individual items in the tuple can then be queried with the Item property:

Console.WriteLine(MultiplesOfTwo.Item2);

Tuples might contain up to seven elements; if you want to add more items, you have to pass in another tuple to the Rest parameter:

var multiples = new Tuple<int, int, int, int, int, int, int,Tuple<int,int,int>>(2, 4, 6, 8,
10, 12, 14, new Tuple<int,int,int>(3,6,9));

Items in the second tuple can be accessed by querying the Rest property:

Console.WriteLine(multiples.Rest.Item1);

4.10.7. System.Numerics.Complex

Mathematicians will be glad of the addition of the new Complex type: a structure for representing and manipulating complex numbers, meaning that they will no longer have to utilize open source libraries or projects. Complex represents both a real and imaginary number, and contains support for both rectangular and polar coordinates:

Complex c1 = new Complex(8, 2);
Complex c2 = new Complex(8, 2);
Complex c3 = c1 + c2;

I am afraid my math skills aren't up to saying much more about this type, so let's move on.

4.10.8. System.IntPtr and System.UIntPtr

Addition and subtraction operators are now supported for System.IntPtr and System.UIntPtr. Add() and Subtract() methods have also been added to these types.

4.10.9. Tail Recursion

The CLR contains support for tail recursion, although this is only currently accessible through F#.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.75.27