Value Types | Robert’s C# Musings

Archive

Posts Tagged ‘value types’

Value Types vs. Reference Types

January 9th, 2009

One area of C# that causes confusion is the difference between value and reference types.

 

Reference Types

 

Let’s talk about reference types for a moment. A common reference type used in .NET is StringBuilder (others include Form, String, All Arrays, Classes, and Delegates). Take a look at this example, do you know what the output will be?

   1: private void Main_Load(object sender, EventArgs e)
   2: {
   3:  
   4:     StringBuilder X = new StringBuilder("It's Raining In ");
   5:     AppendCityName(ref X);
   6:     Console.WriteLine(X.ToString());
   7: }
   8:  
   9: private void AppendCityName(ref StringBuilder Source) {
  10:  
  11:     Source.Append("Seattle");
  12:  
  13: }

 

The correct answer is “It’s Raining In Seattle”. We pass our new StringBuilder into AppendCityName explicitly by reference and AppendCityName acts on the reference to the original StringBuilder. Nothing too surprising here.

 

Now try this one (I’ve taken away the “ref” keyword – resulting in X being passed By Value), what will the output be?

 

   1: private void Main_Load(object sender, EventArgs e)
   2: {
   3:  
   4:     StringBuilder X = new StringBuilder("It's Raining In ");
   5:     AppendCityName(X);
   6:     Console.WriteLine(X.ToString());
   7: }
   8:  
   9: private void AppendCityName(StringBuilder Source) {
  10:  
  11:     Source.Append("Seattle");
  12:  
  13: }

 

Did you guess “It’s Raining In Seattle”? The output is identical to the first example.

 

What’s going on here?

Did you expect the output to be “It’s Raining In ”?

StringBuilder is a reference type. That is to say, it lives on the heap (instead of the stack), and the behind-the-scenes value of X in the example above is just the address to the new StringBuilder object created on the heap.

In both examples, only the address to the original StringBuilder on the heap is being passed into the method, and even in the By Value (Second) Example, the StringBuilder data is NOT being copied or moved around at all.

There is a difference between the two, however. In the first example, both X in Main_Load() and Source in AppendCityName() point directly to the same address on the heap. In the second example, Source points to X in Main_Load(), which points to the StringBuilder on the heap.

 

Why is this important?

Passing a reference type by value or by reference is functionally the same 90% of the time. The problem is the remaining 10% of the time. Take the following example:

 

   1: private void Main_Load(object sender, EventArgs e)
   2: {
   3:  
   4:     StringBuilder X = new StringBuilder("It's Raining In ");
   5:     AppendCityName(ref X);
   6:     Console.WriteLine(X.ToString());
   7: }
   8:  
   9: private void AppendCityName(ref StringBuilder Source) {
  10:  
  11:     Source.Append("Seattle");
  12:     Source = null;
  13:  
  14: }

…which, if you were to execute, unfortunately results in…

exception-01b

Ooops. Because the StringBuilder is passed by reference, AppendCityName() is working with the original reference to the object, and not a copy of the reference. If we were passing the StringBuilder by value, this would have never happened. When in doubt, pass reference types by value and not by reference!

 

Value Types

 

Value types are the complimenting type to reference types. Instead of being stored on the heap, value types are stored on the stack (unless boxed). Integers, Booleans, and Structs are common examples of value types.

When value types are passed By Value, the actual value is copied and there are no references involved. When value types are passed By Reference, the method argument is initialized with the address pointing back to the original value in the calling routine.

 

Here’s an example of passing a value type by reference:

 

   1: private void Main_Load(object sender, EventArgs e)
   2: {
   3:  
   4:     int TotalDragonCount = 1;
   5:     IncrementDragons(ref TotalDragonCount);
   6:     Console.Write(TotalDragonCount);
   7:  
   8: }
   9:  
  10: private void IncrementDragons(ref int OriginalDragonCount) {
  11:  
  12:     OriginalDragonCount++;
  13:  
  14: }

 

The output is 2. TotalDragonCount is passed into IncrementDragons(), which properly works with a reference to the original value before exiting.

 

Here’s what happens with the same example, but missing the ref keyword (Passing By Value):

 

   1: private void Main_Load(object sender, EventArgs e)
   2: {
   3:  
   4:     int TotalDragonCount = 1;
   5:     IncrementDragons(TotalDragonCount);
   6:     Console.Write(TotalDragonCount);
   7:  
   8: }
   9:  
  10: private void IncrementDragons(int OriginalDragonCount) {
  11:  
  12:     OriginalDragonCount++;
  13:  
  14: }

The output is 1. Notice the difference between value types and reference types? If int was a reference type instead of a value type, this last example would have returned 2.

 

The Takeaway

 

Value types behave very intuitively, but be careful with reference types, especially when passing them By Reference. Know the (subtle) difference between passing value types By Reference and passing reference types By Value (A Value type passed by reference simply points back to the original value type, while a reference type by value creates a copy of the reference (address) inside the method being invoked)

Share/Save/Bookmark

C# , ,

Using | Robert’s C# Musings

Archive

Posts Tagged ‘using’

Black Belt C# Series – Language Keywords

April 13th, 2009

The Black Belt C# series aims to uncover powerful but lesser-known features of the C# language. Each article introduces a few of these features and shows you how to use them to take your programming to the next level.

 

The “as” Keyword

The as operator is a quick way to try to cast an object to a specific type. The operator returns null if the cast fails, instead of raising an exception.

There are cases where you may have an incoming object that may be a specific type. Take a look at this X10 (home automation) example:

 

   1: private class X10Device { }
   2: private class DoorSensor : X10Device { }
   3: private class LightSwitch : X10Device { public bool On { get; set; } }
   4:  
   5: private void Controller_DeviceChangedState(X10Device Source)
   6: {
   7:     //...respond to device change based on type
   8: }

 

In this example, imagine an X10 controller is wired up to our DeviceChanged…() method and it’s called every time an x10 device changes state. Any type of X10 device could be passed into the method and we can’t be sure of the exact type of device until we check for it at runtime.

Lets say that we only want to pay attention to light switches and ignore the other device types. There are a few ways we could attempt to single out light switches and start working with them.

Here’s a traditional way of doing this:

   1: private void Controller_DeviceChangedState(X10Device Source)
   2: {
   3:  
   4:     if (Source is LightSwitch)
   5:     {
   6:         LightSwitch SourceLightSwitch = (LightSwitch)Source;
   7:  
   8:         if (SourceLightSwitch.On == true)
   9:         {
  10:             MessageBox.Show("Light Turned On!");
  11:         }
  12:  
  13:     }
  14:  
  15: }

 

This example uses the “is” keyword to single out light switches. Then it creates a new variable that is certainly a light switch and wires it up to the Source reference knowing with full certainty that the cast will succeed.

 

Here’s an alternative way to accomplish the same thing, by using the “as” keyword:

   1: private void Controller_DeviceChangedState(X10Device Source)
   2: {
   3:  
   4:     LightSwitch SourceLightSwitch = Source as LightSwitch;
   5:  
   6:     if (SourceLightSwitch != null)
   7:     {
   8:         if (SourceLightSwitch.On == true)
   9:         {
  10:             MessageBox.Show("Light Turned On!");
  11:         }
  12:     }
  13:  
  14: }

If you ask me, this example is a little bit more succinct and readable. It also neatly groups together the case for Source being null or a different type (such as a DoorSensor).

 

If you can afford a slightly lower readability, the “as” statement also allows for a more compressed syntax where the cast attempt and check are performed all on the same line:

   1: LightSwitch SourceLightSwitch = null;
   2:  
   3: if ((SourceLightSwitch = Source as LightSwitch) != null)
   4: {
   5:     if (SourceLightSwitch.On == true)
   6:     {
   7:         MessageBox.Show("Light Turned On!");
   8:     }
   9: }

 

 

The “using” Keyword

The using keyword is an unusual case of two separate (but related) keywords rolled into one name.

Aliases (the using directive)

Aliases can save you a lot of time when you have oft-used complex generics and namespaces. The using directive allows you to define the composition of these types in one place instead of typing them out over and over again. Here’s an example with nested dictionaries:

 

   1: using ComplexDictionary = Dictionary<int, Dictionary<string, List<string>>>;
   2:  
   3: public partial class Main : Form
   4: {
   5:     ComplexDictionary MainComplexDictionary = new ComplexDictionary();
   6:     ComplexDictionary SecondaryComplexDictionary = new ComplexDictionary();
   7:  
   8:     public Main()
   9:     {
  10:         InitializeComponent();
  11:     }
  12:  
  13: }

As you can see, the using directive safely abstracts the “ComplexDictionary” type to a single location and is easily readable. Changing the ComplexDictionary type would be a simple task, no matter how many times it’s used throughout the code. Furthermore, creating further new ComplexDictionary variables is now a snap. Here’s the ugly alternative:

   1: public partial class Main : Form
   2: {
   3:     Dictionary<int, Dictionary<string, List<string>>> MainDictionary = 
   4:         new Dictionary<int, Dictionary<string, List<string>>>();
   5:  
   6:     Dictionary<int, Dictionary<string, List<string>>> SecondaryDictionary = 
   7:         new Dictionary<int, Dictionary<string, List<string>>>();
   8:  
   9:     public Main()
  10:     {
  11:         InitializeComponent();
  12:     }
  13:  
  14: }

 

 

Explicit Object Scope (the using statement)

The using statement is a bulletproof way to use disposable objects. Here’s an example:

   1: using (Form NewForm = new Form())
   2: {
   3:     NewForm.Enabled = true;
   4:     NewForm.StartPosition = FormStartPosition.CenterScreen;
   5:     NewForm.Size = new Size() { Height = 100, Width = 100 };
   6:     NewForm.ShowDialog();
   7: }

In this example, a new form is created and displayed and execution blocks at ShowDialog() until the form is closed. As soon as the form is closed by the user NewForm.Dispose() is called and NewForm goes out of scope – automatically.

This is functionally equivalent to the following code:

   1: {
   2:     Form NewForm = new Form();
   3:  
   4:     try
   5:     {
   6:         NewForm.Enabled = true;
   7:         NewForm.StartPosition = FormStartPosition.CenterScreen;
   8:         NewForm.Size = new Size() { Height = 100, Width = 100 };
   9:         NewForm.ShowDialog();
  10:     }
  11:     finally
  12:     {
  13:         if (NewForm != null) ((IDisposable)NewForm).Dispose();
  14:     }
  15:  
  16:  
  17: }

The using statement makes it easy to contain object scope and ensure that objects are disposed properly every time. Taking advantage of the using statement is a great way to improve quality while not sacrificing readability.

 

The “checked” and “unchecked” Keywords

The checked and unchecked keywords are useful for controlling what happens when an arithmetic operation overflows. By default, .NET projects created in Visual Studio will allow arithmetic overflow to happen silently and without warning.

 

Default Overflow Example – Outputs “-2” with default project configuration
   1: //32,767 is the maximum value for a short 
   2: short FirstValue = 32767;
   3: short SecondValue = 32767;
   4:  
   5: //Outputs -2
   6: Debug.WriteLine((short)(FirstValue + SecondValue));

 

image Global overflow checking is not turned on by default because it’s a significant performance hit and arithmetic overflow is not really a common occurrence.

You can turn on overflow checking by opening up your project advanced build settings (left) and checking the appropriate box but it’s generally a better practice to selectively enable overflow checking instead.

These two keywords were created to give developers just that precision level of control needed over overflow checking. To use the checked keyword, simply wrap your math statement inside a “Checked { }” block.

 

Tip:

The “Checked” and “Unchecked” keywords only apply to code directly in the specified block and do not extend to arithmetic in nested function calls. Calling a function from within your checked block will not cause overflow checking to occur inside the called function.

 

Checked Overflow Example – Raises Exception
   1: //32,767 is the maximum value for a short 
   2: short FirstValue = 32767;
   3: short SecondValue = 32767;
   4:  
   5: checked
   6: {
   7:     //Raises Overflow Exception
   8:     Debug.WriteLine((short)(FirstValue + SecondValue));
   9: }

Any overflows occurring inside the parenthesis will safely raise an OverflowException, failing loudly:

 

image

 

Correspondingly, if you do enable global overflow checking, you can selectively disable it by wrapping statements inside an “Unchecked { }” block. This is especially useful for reaping performance benefits in tight loops where you can prove that overflow will not occur. Again, unchecked { } will only have performance benefits if you have manually enabled overflow checking.

Unchecked Example – Assumes global overflow checking manually enabled
   1: unchecked
   2: {
   3:     //Index will never exceed 3,276.
   4:     for (int Index = 0; Index <= 3276; Index++)
   5:     {
   6:         //Will never overflow – Index * 10 will never exceed 32,760
   7:         Debug.WriteLine((short)(Index * 10));
   8:     }
   9: }

 

 

How does overflow checking work?

Overflow checking is effectively added into your project at compile time. Turning on global overflow checking or using checked { } blocks causes the compiler to generate slightly different IL to accommodate your request. Here’s the IL from the previous example of adding two shorts:

 

Unchecked – Adds FirstValue and SecondValue
   1: .maxstack 2
   2: .locals init (
   3:     [0] int16 FirstValue,
   4:     [1] int16 SecondValue)
   5: L_0000: nop 
   6: L_0001: ldc.i4 0x7fff
   7: L_0006: stloc.0 
   8: L_0007: ldc.i4 0x7fff
   9: L_000c: stloc.1 
  10: L_000d: nop 
  11: L_000e: ldloc.0 
  12: L_000f: ldloc.1 
  13: L_0010: add 
  14: L_0011: conv.i2 
  15: L_0012: box int16
  16: L_0017: call void [System]System.Diagnostics.Debug::WriteLine(object)
  17: L_001c: nop 
  18: L_001d: nop 
  19: L_001e: ret 

 

Checked – Adds FirstValue and SecondValue with Overflow Check
   1: .maxstack 2
   2:  .locals init (
   3:      [0] int16 FirstValue,
   4:      [1] int16 SecondValue)
   5:  L_0000: nop 
   6:  L_0001: ldc.i4 0x7fff
   7:  L_0006: stloc.0 
   8:  L_0007: ldc.i4 0x7fff
   9:  L_000c: stloc.1 
  10:  L_000d: nop 
  11:  L_000e: ldloc.0 
  12:  L_000f: ldloc.1 
  13:  L_0010: add.ovf 
  14:  L_0011: conv.ovf.i2 
  15:  L_0012: box int16
  16:  L_0017: call void [System]System.Diagnostics.Debug::WriteLine(object)
  17:  L_001c: nop 
  18:  L_001d: nop 
  19:  L_001e: ret 

 

As you can see, the checked block doesn’t radically alter the output IL. Can you spot the overflow check? In the checked (second) example, the compiler emitted “add.ovf” on line 13 instead of “add”. That’s pretty much it (apart from another check on line 14 for an implicit conversion).

The special IL “add.ovf” performs an overflow check before moving the result onto the stack. Intermediate language also contains similar versions for subtraction (sub.ovf), multiplication (mul.ovf), and numeric conversion.

Share/Save/Bookmark

Black Belt, C# , , , , ,

Unchecked | Robert’s C# Musings

Archive

Posts Tagged ‘unchecked’

Black Belt C# Series – Language Keywords

April 13th, 2009

The Black Belt C# series aims to uncover powerful but lesser-known features of the C# language. Each article introduces a few of these features and shows you how to use them to take your programming to the next level.

 

The “as” Keyword

The as operator is a quick way to try to cast an object to a specific type. The operator returns null if the cast fails, instead of raising an exception.

There are cases where you may have an incoming object that may be a specific type. Take a look at this X10 (home automation) example:

 

   1: private class X10Device { }
   2: private class DoorSensor : X10Device { }
   3: private class LightSwitch : X10Device { public bool On { get; set; } }
   4:  
   5: private void Controller_DeviceChangedState(X10Device Source)
   6: {
   7:     //...respond to device change based on type
   8: }

 

In this example, imagine an X10 controller is wired up to our DeviceChanged…() method and it’s called every time an x10 device changes state. Any type of X10 device could be passed into the method and we can’t be sure of the exact type of device until we check for it at runtime.

Lets say that we only want to pay attention to light switches and ignore the other device types. There are a few ways we could attempt to single out light switches and start working with them.

Here’s a traditional way of doing this:

   1: private void Controller_DeviceChangedState(X10Device Source)
   2: {
   3:  
   4:     if (Source is LightSwitch)
   5:     {
   6:         LightSwitch SourceLightSwitch = (LightSwitch)Source;
   7:  
   8:         if (SourceLightSwitch.On == true)
   9:         {
  10:             MessageBox.Show("Light Turned On!");
  11:         }
  12:  
  13:     }
  14:  
  15: }

 

This example uses the “is” keyword to single out light switches. Then it creates a new variable that is certainly a light switch and wires it up to the Source reference knowing with full certainty that the cast will succeed.

 

Here’s an alternative way to accomplish the same thing, by using the “as” keyword:

   1: private void Controller_DeviceChangedState(X10Device Source)
   2: {
   3:  
   4:     LightSwitch SourceLightSwitch = Source as LightSwitch;
   5:  
   6:     if (SourceLightSwitch != null)
   7:     {
   8:         if (SourceLightSwitch.On == true)
   9:         {
  10:             MessageBox.Show("Light Turned On!");
  11:         }
  12:     }
  13:  
  14: }

If you ask me, this example is a little bit more succinct and readable. It also neatly groups together the case for Source being null or a different type (such as a DoorSensor).

 

If you can afford a slightly lower readability, the “as” statement also allows for a more compressed syntax where the cast attempt and check are performed all on the same line:

   1: LightSwitch SourceLightSwitch = null;
   2:  
   3: if ((SourceLightSwitch = Source as LightSwitch) != null)
   4: {
   5:     if (SourceLightSwitch.On == true)
   6:     {
   7:         MessageBox.Show("Light Turned On!");
   8:     }
   9: }

 

 

The “using” Keyword

The using keyword is an unusual case of two separate (but related) keywords rolled into one name.

Aliases (the using directive)

Aliases can save you a lot of time when you have oft-used complex generics and namespaces. The using directive allows you to define the composition of these types in one place instead of typing them out over and over again. Here’s an example with nested dictionaries:

 

   1: using ComplexDictionary = Dictionary<int, Dictionary<string, List<string>>>;
   2:  
   3: public partial class Main : Form
   4: {
   5:     ComplexDictionary MainComplexDictionary = new ComplexDictionary();
   6:     ComplexDictionary SecondaryComplexDictionary = new ComplexDictionary();
   7:  
   8:     public Main()
   9:     {
  10:         InitializeComponent();
  11:     }
  12:  
  13: }

As you can see, the using directive safely abstracts the “ComplexDictionary” type to a single location and is easily readable. Changing the ComplexDictionary type would be a simple task, no matter how many times it’s used throughout the code. Furthermore, creating further new ComplexDictionary variables is now a snap. Here’s the ugly alternative:

   1: public partial class Main : Form
   2: {
   3:     Dictionary<int, Dictionary<string, List<string>>> MainDictionary = 
   4:         new Dictionary<int, Dictionary<string, List<string>>>();
   5:  
   6:     Dictionary<int, Dictionary<string, List<string>>> SecondaryDictionary = 
   7:         new Dictionary<int, Dictionary<string, List<string>>>();
   8:  
   9:     public Main()
  10:     {
  11:         InitializeComponent();
  12:     }
  13:  
  14: }

 

 

Explicit Object Scope (the using statement)

The using statement is a bulletproof way to use disposable objects. Here’s an example:

   1: using (Form NewForm = new Form())
   2: {
   3:     NewForm.Enabled = true;
   4:     NewForm.StartPosition = FormStartPosition.CenterScreen;
   5:     NewForm.Size = new Size() { Height = 100, Width = 100 };
   6:     NewForm.ShowDialog();
   7: }

In this example, a new form is created and displayed and execution blocks at ShowDialog() until the form is closed. As soon as the form is closed by the user NewForm.Dispose() is called and NewForm goes out of scope – automatically.

This is functionally equivalent to the following code:

   1: {
   2:     Form NewForm = new Form();
   3:  
   4:     try
   5:     {
   6:         NewForm.Enabled = true;
   7:         NewForm.StartPosition = FormStartPosition.CenterScreen;
   8:         NewForm.Size = new Size() { Height = 100, Width = 100 };
   9:         NewForm.ShowDialog();
  10:     }
  11:     finally
  12:     {
  13:         if (NewForm != null) ((IDisposable)NewForm).Dispose();
  14:     }
  15:  
  16:  
  17: }

The using statement makes it easy to contain object scope and ensure that objects are disposed properly every time. Taking advantage of the using statement is a great way to improve quality while not sacrificing readability.

 

The “checked” and “unchecked” Keywords

The checked and unchecked keywords are useful for controlling what happens when an arithmetic operation overflows. By default, .NET projects created in Visual Studio will allow arithmetic overflow to happen silently and without warning.

 

Default Overflow Example – Outputs “-2” with default project configuration
   1: //32,767 is the maximum value for a short 
   2: short FirstValue = 32767;
   3: short SecondValue = 32767;
   4:  
   5: //Outputs -2
   6: Debug.WriteLine((short)(FirstValue + SecondValue));

 

image Global overflow checking is not turned on by default because it’s a significant performance hit and arithmetic overflow is not really a common occurrence.

You can turn on overflow checking by opening up your project advanced build settings (left) and checking the appropriate box but it’s generally a better practice to selectively enable overflow checking instead.

These two keywords were created to give developers just that precision level of control needed over overflow checking. To use the checked keyword, simply wrap your math statement inside a “Checked { }” block.

 

Tip:

The “Checked” and “Unchecked” keywords only apply to code directly in the specified block and do not extend to arithmetic in nested function calls. Calling a function from within your checked block will not cause overflow checking to occur inside the called function.

 

Checked Overflow Example – Raises Exception
   1: //32,767 is the maximum value for a short 
   2: short FirstValue = 32767;
   3: short SecondValue = 32767;
   4:  
   5: checked
   6: {
   7:     //Raises Overflow Exception
   8:     Debug.WriteLine((short)(FirstValue + SecondValue));
   9: }

Any overflows occurring inside the parenthesis will safely raise an OverflowException, failing loudly:

 

image

 

Correspondingly, if you do enable global overflow checking, you can selectively disable it by wrapping statements inside an “Unchecked { }” block. This is especially useful for reaping performance benefits in tight loops where you can prove that overflow will not occur. Again, unchecked { } will only have performance benefits if you have manually enabled overflow checking.

Unchecked Example – Assumes global overflow checking manually enabled
   1: unchecked
   2: {
   3:     //Index will never exceed 3,276.
   4:     for (int Index = 0; Index <= 3276; Index++)
   5:     {
   6:         //Will never overflow – Index * 10 will never exceed 32,760
   7:         Debug.WriteLine((short)(Index * 10));
   8:     }
   9: }

 

 

How does overflow checking work?

Overflow checking is effectively added into your project at compile time. Turning on global overflow checking or using checked { } blocks causes the compiler to generate slightly different IL to accommodate your request. Here’s the IL from the previous example of adding two shorts:

 

Unchecked – Adds FirstValue and SecondValue
   1: .maxstack 2
   2: .locals init (
   3:     [0] int16 FirstValue,
   4:     [1] int16 SecondValue)
   5: L_0000: nop 
   6: L_0001: ldc.i4 0x7fff
   7: L_0006: stloc.0 
   8: L_0007: ldc.i4 0x7fff
   9: L_000c: stloc.1 
  10: L_000d: nop 
  11: L_000e: ldloc.0 
  12: L_000f: ldloc.1 
  13: L_0010: add 
  14: L_0011: conv.i2 
  15: L_0012: box int16
  16: L_0017: call void [System]System.Diagnostics.Debug::WriteLine(object)
  17: L_001c: nop 
  18: L_001d: nop 
  19: L_001e: ret 

 

Checked – Adds FirstValue and SecondValue with Overflow Check
   1: .maxstack 2
   2:  .locals init (
   3:      [0] int16 FirstValue,
   4:      [1] int16 SecondValue)
   5:  L_0000: nop 
   6:  L_0001: ldc.i4 0x7fff
   7:  L_0006: stloc.0 
   8:  L_0007: ldc.i4 0x7fff
   9:  L_000c: stloc.1 
  10:  L_000d: nop 
  11:  L_000e: ldloc.0 
  12:  L_000f: ldloc.1 
  13:  L_0010: add.ovf 
  14:  L_0011: conv.ovf.i2 
  15:  L_0012: box int16
  16:  L_0017: call void [System]System.Diagnostics.Debug::WriteLine(object)
  17:  L_001c: nop 
  18:  L_001d: nop 
  19:  L_001e: ret 

 

As you can see, the checked block doesn’t radically alter the output IL. Can you spot the overflow check? In the checked (second) example, the compiler emitted “add.ovf” on line 13 instead of “add”. That’s pretty much it (apart from another check on line 14 for an implicit conversion).

The special IL “add.ovf” performs an overflow check before moving the result onto the stack. Intermediate language also contains similar versions for subtraction (sub.ovf), multiplication (mul.ovf), and numeric conversion.

Share/Save/Bookmark

Black Belt, C# , , , , ,

Type Inference | Robert’s C# Musings

Archive

Posts Tagged ‘type inference’

Black Belt C# Series – Syntax

April 4th, 2009

The Black Belt C# series aims to uncover powerful but lesser-known features of the C# language. Each article introduces a few of these features and shows you how to use them to take your programming to the next level.
 

The “??” Operator

This granule of syntactical sugar, known as the the “Null Coalescing Operator”, provides a quick way to check and react to null values. As an example, lets say we have a widget name which came from an external source. Programming defensively, it’s always good idea to check reference types for null before working with them. Here’s an example of the code that may be written without using the operator:

 

   1: string WidgetName = DivineWidgetNameFromEther();
   2: 
   3: if (WidgetName != null)
   4: {
   5:     System.Diagnostics.Debug.WriteLine(WidgetName);
   6: }
   7: else
   8: {
   9:     System.Diagnostics.Debug.WriteLine("WidgetName is null");
  10: }

(10 Lines, 294 Characters)
 
 
This first example branches off into two nearly identical paths. This redundancy is an innocent mistake, but can add up quickly in a large project. There are a few ways you could go about refactoring this, let me show you the best method in this case:
 
   1: string WidgetName = DivineWidgetNameFromEther();
   2: 
   3: System.Diagnostics.Debug.WriteLine(WidgetName ?? "WidgetName is null");

(3 Lines and 124 Characters)

 

This, vastly superior version, produces identical output to the first. If WidgetName is not null, then it’s simply written to the output window. However, if WidgetName does happen to be null, “WidgetName” is null” is safely written instead. This is a great way to unobtrusively improve quality in your program without sacrificing readability.

 

Black Belt Tip: Lazy Instantiation Made Easy

Leverage the null coalescing operator to achieve lazy instantiation with manually implemented properties:

   1: private List<Widget> _Widgets = null;
   2: public List<Widget> Widgets
   3: {
   4:     get { return _Widgets ?? (_Widgets = new List<Widget>()); }
   5: }

 

 

Automatic Properties

Auto-Implemented properties are a nice shorthand (C# 3+) for expressing a public property and a private (although inaccessible) field… without having to type all of that out. Have a look:

 

   1: /// <summary>
   2: /// This is a valid property and NOT a field.
   3: /// </summary>
   4: private string WidgetDescription { get; set; }

 

This is a perfectly valid property, backed by a private field that is created automatically but is inaccessible. Here is the disassembly:

 

   1: .property instance string WidgetDescription
   2: {
   3:     .get instance string BlackBeltCSharp.Form1::get_WidgetDescription()
   4:     .set instance void BlackBeltCSharp.Form1::set_WidgetDescription(string)
   5: }
   6: 
   7: 
   8: .field private string <WidgetDescription>k__BackingField
   9: {
  10:     .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor()
  11: }

(k__BackingField and the get_…() and set_…() methods are generated automatically by the compiler)
 

You can designate a different scope for the getter and for the setter, without leaving automatic properties. For Example:

   1: public string WidgetDescription { get; private set; }

…is perfectly valid and renders the property read-only from outside of the current class.
 
 
 

Advanced Generics

Taking advantage of generics, introduced in .NET 2.0, is a great way to improve your productivity while layering on type-safety and added performance benefits (up to 200% when working with value types such as integers). To review, here is a sample generic method and usage:

Sample Generic Method
   1: /// <summary>
   2:  /// Selects and returns an item at (pseudo)random from the supplied list
   3:  /// </summary>
   4:  /// <typeparam name="T">Any Type</typeparam>
   5:  /// <param name="FromList">Source list from which to pick an item from</param>
   6:  /// <returns>(pseudo)Randomly selected item</returns>
   7:  private T SelectRandom<T>(List<T> FromList)
   8:  {
   9:      Debug.Assert(FromList != null, "FromList (of type " + typeof(T).Name + ") is null.");
  10: 
  11:      //Picks a pseudo-random index in "FromList"
  12:      int RandomlySelectedIndex =
  13:          new Random((int)(DateTime.Now.Ticks % 0x7FFFFFFF)).Next(FromList.Count);
  14: 
  15:      //Returns item at randomly chosen index
  16:      return FromList[RandomlySelectedIndex];
  17: 
  18:  }

 
Sample Usage
   1: List<String> Names = new List<String>() { "Daniel Dennett", "John Locke", "Saul Kripke" };
   2: List<int> Numbers = new List<int>() { 2, 5, 7 };
   3: 
   4: Debug.WriteLine("Read " + SelectRandom<int>(Numbers) +
   5:     " books from " + SelectRandom<string>(Names));

The usage outputs something like “Read 7 books from John Locke”. The important thing to notice is the use of the same generic “SelectRandom” method for both integers and strings.

 

Type Inference

It’s possible for the c# compiler to infer the type to be used. For example, this is perfectly legal:

   1: Debug.WriteLine("Read " + SelectRandom(Numbers) +
   2:     " books from..." + SelectRandom(Names));

 

Where T : new()

This special constraint limits acceptable types to those which feature a public, parameterless constructor. This allows for some really special syntax inside a generic class. Have a look:

   1: class ConstrainedGenericClass<T> where T : new()
   2: {
   3:     private T NewItemOfTypeT = new T();
   4: }

 

Using the “new()” constraint unlocks the ability to easily instantiate a new version of the specified class type. This is just the tip of the iceberg, for a complete list of constraints, visit:

http://msdn.microsoft.com/en-us/library/6b0scde8(VS.80).aspx

 

Currying

Likely the most advanced and confusing topic surrounding generics in c#, currying is the process of distributing an argument list over several functions, instead of one. For example, instead of having one function that takes three arguments, you can have three functions taking one argument, each building on the next. Let me show you a few examples:

 

Example Without Currying
   1: private void DoWork()
   2: {
   3:     //Outputs 11
   4:     Debug.WriteLine(AddNumbers(1, 3, 7));
   5: }
   6: 
   7: //Returns sum of three integers
   8: private int AddNumbers(int X, int Y, int Z)
   9: {
  10:     return X + Y + Z;
  11: }

 

Example With Currying
   1: private void DoWork()
   2: {
   3:     var CurriedNumberAdder = Curry(AddNumbersWork);
   4: 
   5:     //Outputs 11
   6:     Debug.WriteLine(CurriedNumberAdder(1)(3)(7));
   7: }
   8: 
   9: Func<int,int,int,int> AddNumbersWork = (X, Y, Z) => X + Y + Z;
  10: 
  11: //Standard Curry Function
  12: private Func<T1, Func<T2, Func<T3, T4>>> Curry<T1, T2, T3, T4>(Func<T1, T2, T3, T4> function)
  13: {
  14:     return a => b => c => function(a, b, c);
  15: }

If you haven’t yet delved into functional programming then this example may be confusing and the benefit may not be immediately obvious. What’s happening here is each function calls the next, while contributing its argument. This process continues until it gets to the last function (X + Y + Z), which in this case defines what should happen with the arguments that have been assembled.

There are a few interesting benefits to this massive overhead of complexity. First, it’s possible to slowly assemble the function in bits and pieces over many lines. Example:

Example of Calling One Argument at a Time
   1: private void DoWork()
   2: {
   3:     var CurriedNumberAdder = Curry(AddNumbersWork);
   4: 
   5:     //...Do Something Else Here
   6: 
   7:     var FirstResult = CurriedNumberAdder(1);
   8: 
   9:     //...Do Something Else Here
  10: 
  11:     var SecondResult = FirstResult(3);
  12: 
  13:     //Outputs 11
  14:     Debug.WriteLine(SecondResult(7));
  15: }

 

This may be useful for reducing the scope and span of variables that contribute to your curried function. More importantly, by encapsulating combinations of arguments inside a variable, it opens up new possibilities for reuse:

Example Reusing Curried Functions
   1: private void DoWork()
   2: {
   3:     var CurriedNumberAdder = Curry(AddNumbersWork);
   4: 
   5:     var FirstResult = CurriedNumberAdder(1);
   6:     var SecondResult = FirstResult(3);
   7: 
   8:     //Outputs 5
   9:     Debug.WriteLine(SecondResult(1));
  10: 
  11:     //Outputs 14
  12:     Debug.WriteLine(SecondResult(10));
  13: 
  14:     //Outputs 104
  15:     Debug.WriteLine(SecondResult(100));
  16: }

Share/Save/Bookmark

Black Belt, C# , , , , , , ,

Threads | Robert’s C# Musings

Archive

Posts Tagged ‘threads’

Threading Tips and Tricks

January 11th, 2009

 

too-much-threading

Have you ever had trouble designing or debugging multi-threaded applications?

 

Asynchronous programming can be a struggle without a toolbox of techniques and tips to help. Let me show you what I’ve learned to make multi-threading in C# faster to implement and easier to manage!

 

Use the Threads Window

Visual Studio (Standard and up) has a tool for viewing running threads, aptly named the “Threads” window (Start your application in the debugger and then click on Debug->Windows->Threads [or CTRL+D, T]. Break execution to activate the window. From there, you can see which threads are running and minimal information about each one.

threads-window2

The really useful feature about the Threads window is that it allows you to update the call stack window to the thread of your choosing. Just double click on another thread to synchronize the call stack window with the new thread.

thread-menu

Another useful feature is the ability to Freeze and Unfreeze threads without using the Immediate window. Just right click on a given thread to pull up the relevant menu.

Freezing other threads is exceptionally useful if you are trying to step through execution in just one thread and it’s safe to temporarily ignore the others.

Without freezing the other threads, the debugger is likely to move you around from the context of one thread to another while stepping through, wasting your time and energy in the process.

 

Name your threads.

Use the Thread.Name property to assign a descriptive name to each of your threads. For Example:

   1: Thread YearEndProfitReportThread = new Thread(CreateYearEndProfitReport);
   2: YearEndProfitReportThread.Name = "Year End Profits Calculator";
   3: YearEndProfitReportThread.Start();

 

Now, in the Threads window you will be able to see the name you assigned instead of “<No Name>”.

threads-window-named

This is useful while debugging, because of instead of selecting each thread until you find the right one you can jump to exactly the one you need.

 

Leverage the power of C# 3.0

Language specification 3 introduced a few powerful tools such as object initializers and lambda expressions that can apply to threading. These are very powerful tools that obviously need to weighed carefully with readability and maintainability but can dramatically cut down on the amount of code to write.

Note: Parameterless lambdas are only being used here because they are slightly more succinct than using anonymous methods.

Quick and (Very) Dirty Example

   1: (new Thread(() => {
   2:     DoLongRunningWork();
   3:     MessageBox.Show("Long Running Work Finished!");
   4: }) { Name = "Long Running Work Thread",
   5:     Priority = ThreadPriority.BelowNormal }).Start();

 

In only five lines of code, we create a new thread, give it some work to do (via parameterless lambda expression), assign the name and priority (thanks to object initializers) and then trigger it to start. This example assumes reasonable exception handling in the DoLongRunningWork() method and should be wrapped in a try…catch {} block to catch exceptions such as ThreadAbortException (See below for Exception Handling tips).

 

More Practical Example, Hide a Form for X Time

Taking advantage of closures (introduced in 2.0), we can build functions with arguments that are automatically available inside inline lambda statements. Have a look at this example, which hides a form for a certain timespan:

 

   1: private void MakeInvisible(TimeSpan Duration) {
   2:  
   3:     (new System.Threading.Thread(() =>
   4:     {
   5:         try
   6:         {
   7:             this.Invoke(new MethodInvoker(this.Hide));
   8:             System.Threading.Thread.Sleep(Duration);
   9:         }
  10:         catch (ThreadAbortException ThreadAbort)
  11:         {
  12:             //...
  13:         }
  14:         catch (ThreadInterruptedException ThreadInterrupt)
  15:         {
  16:             //...
  17:         }
  18:         finally
  19:         {
  20:             this.Invoke(new MethodInvoker(this.Show));
  21:         }
  22:     }) 
  23:     { 
  24:         Name = "MakeInvisible (" + Duration.ToString() + ")" 
  25:     }
  26:     ).Start();
  27:  
  28: }

 

Using the lambda statement, we are providing the set of instructions to run in our new thread and using property initializers towards the bottom of the function we are setting the thread name. Closures are used with the this keyword and Duration – both of which are passing through to the lambda statement automatically from the host method (MakeInvisible).

Although a bit poor on readability, I think this is a great example of how 3.0 and threading can replace a swath of other (much more complicated) code. To write the same example without the latest language features would take at least a timer and one more method, as well as additional code to wire everything together.

 

Use Airtight Exception Handling

In production applications, it pays you to have the most extensive error handling possible in all of your worker threads. Have a look at the following unsafe code example:

   1: private void UnsafeButton_Click(object sender, EventArgs e)
   2: {
   3:  
   4:     int x = 0;
   5:     int y = 1 / x;
   6:  
   7: }

If you were to start this application outside of the debugger and press the button, at worst you would receive the following dialog box:

divide-by-zero

Bad, but life goes on (via the Continue button). Now, if that same unsafe code is put in a worker thread:

   1: private void UnsafeButton_Click(object sender, EventArgs e)
   2: {
   3:     (new Thread(()=> {
   4:         int x = 0;
   5:         int y = 1 / x;
   6:     })).Start();
   7: }

You are asking for trouble. This is what happens:

stopped-working

The entire application shuts down without details about the exception or a way to continue. (This won’t happen inside the debugger, of course). An alternative to wrapping all of your worker threads in try…catch blocks is to handle the Application.ThreadException Event. This is a quicker way to ensure that your application won’t come to grinding halt when an exception is thrown in a worker thread.

As a final note, be aware that threads are susceptible to the special exceptions ThreadAbortException and ThreadInterruptedException. It’s possible to cancel an initiated abort by handling ThreadAbortException and calling ResetAbort() in the catch block.

Share/Save/Bookmark

C#, Tips and Tricks , , , , , ,

Threads | Robert’s C# Musings

Archive

Posts Tagged ‘threads’

Threading Tips and Tricks

January 11th, 2009

 

too-much-threading

Have you ever had trouble designing or debugging multi-threaded applications?

 

Asynchronous programming can be a struggle without a toolbox of techniques and tips to help. Let me show you what I’ve learned to make multi-threading in C# faster to implement and easier to manage!

 

Use the Threads Window

Visual Studio (Standard and up) has a tool for viewing running threads, aptly named the “Threads” window (Start your application in the debugger and then click on Debug->Windows->Threads [or CTRL+D, T]. Break execution to activate the window. From there, you can see which threads are running and minimal information about each one.

threads-window2

The really useful feature about the Threads window is that it allows you to update the call stack window to the thread of your choosing. Just double click on another thread to synchronize the call stack window with the new thread.

thread-menu

Another useful feature is the ability to Freeze and Unfreeze threads without using the Immediate window. Just right click on a given thread to pull up the relevant menu.

Freezing other threads is exceptionally useful if you are trying to step through execution in just one thread and it’s safe to temporarily ignore the others.

Without freezing the other threads, the debugger is likely to move you around from the context of one thread to another while stepping through, wasting your time and energy in the process.

 

Name your threads.

Use the Thread.Name property to assign a descriptive name to each of your threads. For Example:

   1: Thread YearEndProfitReportThread = new Thread(CreateYearEndProfitReport);
   2: YearEndProfitReportThread.Name = "Year End Profits Calculator";
   3: YearEndProfitReportThread.Start();

 

Now, in the Threads window you will be able to see the name you assigned instead of “<No Name>”.

threads-window-named

This is useful while debugging, because of instead of selecting each thread until you find the right one you can jump to exactly the one you need.

 

Leverage the power of C# 3.0

Language specification 3 introduced a few powerful tools such as object initializers and lambda expressions that can apply to threading. These are very powerful tools that obviously need to weighed carefully with readability and maintainability but can dramatically cut down on the amount of code to write.

Note: Parameterless lambdas are only being used here because they are slightly more succinct than using anonymous methods.

Quick and (Very) Dirty Example

   1: (new Thread(() => {
   2:     DoLongRunningWork();
   3:     MessageBox.Show("Long Running Work Finished!");
   4: }) { Name = "Long Running Work Thread",
   5:     Priority = ThreadPriority.BelowNormal }).Start();

 

In only five lines of code, we create a new thread, give it some work to do (via parameterless lambda expression), assign the name and priority (thanks to object initializers) and then trigger it to start. This example assumes reasonable exception handling in the DoLongRunningWork() method and should be wrapped in a try…catch {} block to catch exceptions such as ThreadAbortException (See below for Exception Handling tips).

 

More Practical Example, Hide a Form for X Time

Taking advantage of closures (introduced in 2.0), we can build functions with arguments that are automatically available inside inline lambda statements. Have a look at this example, which hides a form for a certain timespan:

 

   1: private void MakeInvisible(TimeSpan Duration) {
   2:  
   3:     (new System.Threading.Thread(() =>
   4:     {
   5:         try
   6:         {
   7:             this.Invoke(new MethodInvoker(this.Hide));
   8:             System.Threading.Thread.Sleep(Duration);
   9:         }
  10:         catch (ThreadAbortException ThreadAbort)
  11:         {
  12:             //...
  13:         }
  14:         catch (ThreadInterruptedException ThreadInterrupt)
  15:         {
  16:             //...
  17:         }
  18:         finally
  19:         {
  20:             this.Invoke(new MethodInvoker(this.Show));
  21:         }
  22:     }) 
  23:     { 
  24:         Name = "MakeInvisible (" + Duration.ToString() + ")" 
  25:     }
  26:     ).Start();
  27:  
  28: }

 

Using the lambda statement, we are providing the set of instructions to run in our new thread and using property initializers towards the bottom of the function we are setting the thread name. Closures are used with the this keyword and Duration – both of which are passing through to the lambda statement automatically from the host method (MakeInvisible).

Although a bit poor on readability, I think this is a great example of how 3.0 and threading can replace a swath of other (much more complicated) code. To write the same example without the latest language features would take at least a timer and one more method, as well as additional code to wire everything together.

 

Use Airtight Exception Handling

In production applications, it pays you to have the most extensive error handling possible in all of your worker threads. Have a look at the following unsafe code example:

   1: private void UnsafeButton_Click(object sender, EventArgs e)
   2: {
   3:  
   4:     int x = 0;
   5:     int y = 1 / x;
   6:  
   7: }

If you were to start this application outside of the debugger and press the button, at worst you would receive the following dialog box:

divide-by-zero

Bad, but life goes on (via the Continue button). Now, if that same unsafe code is put in a worker thread:

   1: private void UnsafeButton_Click(object sender, EventArgs e)
   2: {
   3:     (new Thread(()=> {
   4:         int x = 0;
   5:         int y = 1 / x;
   6:     })).Start();
   7: }

You are asking for trouble. This is what happens:

stopped-working

The entire application shuts down without details about the exception or a way to continue. (This won’t happen inside the debugger, of course). An alternative to wrapping all of your worker threads in try…catch blocks is to handle the Application.ThreadException Event. This is a quicker way to ensure that your application won’t come to grinding halt when an exception is thrown in a worker thread.

As a final note, be aware that threads are susceptible to the special exceptions ThreadAbortException and ThreadInterruptedException. It’s possible to cancel an initiated abort by handling ThreadAbortException and calling ResetAbort() in the catch block.

Share/Save/Bookmark

C#, Tips and Tricks , , , , , ,

Threading | Robert’s C# Musings

Archive

Posts Tagged ‘threading’

Practical Introduction to Lambda Expressions

March 31st, 2009

Lambda (11th Letter of Greek Alphabet) Popularized by Python and Ruby, the lambda expression is a powerful shorthand that can be used to significantly speed up c# development. This post deals entirely with using lambda expressions in everyday development, and sidesteps the esoteric mathematical logic that makes them intimidating.

 

Lambda What?

 

A Lambda expression in c# is simply a piece of syntactical sugar for fleshing out a function body where you would normally plug in a delegate (pointing to a function somewhere else). This saves you two or three lines of code per call, speeding up your development (where delegates are required) to light speed and making your code more maintainable.

Because lambdas can only be used where delegates are required, your initial benefit from learning them may be limited. Before looking into lambdas, I avoided using functions in the .NET base class library that required delegates because of the added hassle. Now, after learning how to use lambdas, I seek them out!

Lastly, are you familiar with anonymous methods? Lambda expressions are very similar – just a slightly shorter syntax. Anonymous methods and lambdas compile to the same intermediate language (and have the same performance as a result).

 

 

What does a lambda expression look like?

 

LambdaIdentify 

In the example above, Name => Name.StartsWith(“O”) is the lambda expression. All it does is check if the “Name” passed into it starts with a given letter and returns True/False. The Find() function (not lambda-related) runs this lambda expression against each list item until a match is found. You could use a delegate to another function (like the one below) or an anonymous method in its place, but it would be a lot more code either way.

 

This expression is roughly equivalent to the non-lambda function:

equiv 

(Which could have been plugged into FruitNames.Find() using a delegate by the way. All that was accomplished by using the lambda was saving a few lines of code.)

 

“Name”

Name is the function argument. We could have named this “FruitName”, “F”, or anything else. However, we would have had to remember to change it in the function body at the same time. Lambdas automatically infer variable types from the parent signature. In this case, StartsWith() requires a single string argument, causing “Name” to typed as a string.

 

“=>”

This is the important symbol that tells c# that you are using a lambda expression. It is absolutely required for every lambda expression that you write. Arguments go on the left and your function body goes on the right. Read as “goes to”.

 

“Name.StartsWith(“O”)”

Is plain c# and also the meat of the expression. This simply returns true if the function argument “Name” begins with the letter “O” or false if it does not. In this example, it’s only one line. However, lambdas may be expanded to multiple lines (just wrap your function body in squiggly brackets like any other method) In this case, it is required that we return a Boolean because the parent “Find()” requires a Predicate (Boolean return type):

findreq

(Predicate simply takes in one argument of a given type and returns a Boolean)

 

 

Real-World Examples

Now that you have a basic understanding of what a lambda expression is, and how it might be useful (less code), take a look at a few practical code examples.

 

Predicate Delegates

A predicate is just a function that returns true or false. Imagine helping a friend sort through a box of old items. You pick up each item out of the box and your friend (after looking at the item) either says “throw away” or “keep”. Your friend is acting as a predicate.

Predicates are extremely useful for filtering lists of items and you will find them throughout the framework for this reason. In the first example in this article we used a predicate to sort through a list of fruit by looking at the first letter of each fruit name.

Here is another example using objects instead of strings:

 

   1: private class Book
   2:  {
   3:      public string Author { get; set; }
   4:      public string Name { get; set; }
   5:      public DateTime Published { get; set; }
   6:  }
   7:  
   8:  //Create and fill a list of books
   9:  private List<Book> Books = new List<Book> { 
  10:      new Book { Author="Mcconnell",Name="Code Complete", Published=new DateTime(1993,05,14) },
  11:      new Book { Author="Sussman",Name="SICP (2nd)", Published=new DateTime(1996,06,01) },
  12:      new Book { Author="Hunt",Name="Pragmatic Programmer", Published=new DateTime(1999,10,30) },
  13:  };
  14:  
  15:  
  16:  private IEnumerable<Book> BooksPublishedAfter1995()
  17:  {
  18:      return Books.FindAll(Book => Book.Published > new DateTime(1995, 12, 31));
  19:  }

 

In this example “BooksPublishedAfter1995()” uses a lambda expression as a predicate to compare each when each book was published to a specific date. This function returns a new collection of books containing just SICP and Pragmatic Programmer.

Here’s the a similar multiline lambda that returns books published between 1991 and 1997:

 

   1: private IEnumerable<Book> BooksPublishedBetween1991and1997()
   2: {
   3:     return Books.FindAll(Book => {
   4:  
   5:         return Book.Published >= new DateTime(1991, 01, 01) &&
   6:         Book.Published <= new DateTime(1997, 12, 31);
   7:     
   8:     });
   9: }

 

As you can see, it would be excessive to type out a separate function just for this simple piece of logic. Lambda statements are ideal for this type of filtering.

 

Don’t Forget to stay DRY

(Don’t Repeat Yourself) Lambdas and anonymous methods are a power tools that should be used carefully. Remember to identify and move common predicates into shared functions early instead of using repeated Lambdas throughout your code and creating a maintenance nightmare.

 

 

Absolutely Minimalistic Threading

It is possible to spawn new threads using just the code contained in the lambda statement. In fact, you can do it in only a few lines. A good example for this is when you need to open up a webpage in the default browser from a windows forms application but don’t want the user interface to skip a beat or lock up (as is the case with some firewall software). Lambda expressions paired with a new thread will do the trick:

 

   1: (new System.Threading.Thread(()=> {
   2:  
   3:     try
   4:     {
   5:         System.Diagnostics.Process.Start("http://www.example.com");
   6:     }
   7:     catch (Win32Exception StartException)
   8:     {
   9:         //Likely caused by firewall software such as ZoneAlarm
  10:         MessageBox.Show("Failed to open URL.");
  11:     }
  12:  
  13: })).Start();

 

If you look carefully, you will notice that “()” is used on the left hand side of the lambda. This simply indicates that no arguments are to be used.

For more cool threading lambda expression examples for c#, have a look at my Threading Tips and Tricks post.

Share/Save/Bookmark

C#, Introductions , , , , ,

Threading Tips and Tricks

January 11th, 2009

 

too-much-threading

Have you ever had trouble designing or debugging multi-threaded applications?

 

Asynchronous programming can be a struggle without a toolbox of techniques and tips to help. Let me show you what I’ve learned to make multi-threading in C# faster to implement and easier to manage!

 

Use the Threads Window

Visual Studio (Standard and up) has a tool for viewing running threads, aptly named the “Threads” window (Start your application in the debugger and then click on Debug->Windows->Threads [or CTRL+D, T]. Break execution to activate the window. From there, you can see which threads are running and minimal information about each one.

threads-window2

The really useful feature about the Threads window is that it allows you to update the call stack window to the thread of your choosing. Just double click on another thread to synchronize the call stack window with the new thread.

thread-menu

Another useful feature is the ability to Freeze and Unfreeze threads without using the Immediate window. Just right click on a given thread to pull up the relevant menu.

Freezing other threads is exceptionally useful if you are trying to step through execution in just one thread and it’s safe to temporarily ignore the others.

Without freezing the other threads, the debugger is likely to move you around from the context of one thread to another while stepping through, wasting your time and energy in the process.

 

Name your threads.

Use the Thread.Name property to assign a descriptive name to each of your threads. For Example:

   1: Thread YearEndProfitReportThread = new Thread(CreateYearEndProfitReport);
   2: YearEndProfitReportThread.Name = "Year End Profits Calculator";
   3: YearEndProfitReportThread.Start();

 

Now, in the Threads window you will be able to see the name you assigned instead of “<No Name>”.

threads-window-named

This is useful while debugging, because of instead of selecting each thread until you find the right one you can jump to exactly the one you need.

 

Leverage the power of C# 3.0

Language specification 3 introduced a few powerful tools such as object initializers and lambda expressions that can apply to threading. These are very powerful tools that obviously need to weighed carefully with readability and maintainability but can dramatically cut down on the amount of code to write.

Note: Parameterless lambdas are only being used here because they are slightly more succinct than using anonymous methods.

Quick and (Very) Dirty Example

   1: (new Thread(() => {
   2:     DoLongRunningWork();
   3:     MessageBox.Show("Long Running Work Finished!");
   4: }) { Name = "Long Running Work Thread",
   5:     Priority = ThreadPriority.BelowNormal }).Start();

 

In only five lines of code, we create a new thread, give it some work to do (via parameterless lambda expression), assign the name and priority (thanks to object initializers) and then trigger it to start. This example assumes reasonable exception handling in the DoLongRunningWork() method and should be wrapped in a try…catch {} block to catch exceptions such as ThreadAbortException (See below for Exception Handling tips).

 

More Practical Example, Hide a Form for X Time

Taking advantage of closures (introduced in 2.0), we can build functions with arguments that are automatically available inside inline lambda statements. Have a look at this example, which hides a form for a certain timespan:

 

   1: private void MakeInvisible(TimeSpan Duration) {
   2:  
   3:     (new System.Threading.Thread(() =>
   4:     {
   5:         try
   6:         {
   7:             this.Invoke(new MethodInvoker(this.Hide));
   8:             System.Threading.Thread.Sleep(Duration);
   9:         }
  10:         catch (ThreadAbortException ThreadAbort)
  11:         {
  12:             //...
  13:         }
  14:         catch (ThreadInterruptedException ThreadInterrupt)
  15:         {
  16:             //...
  17:         }
  18:         finally
  19:         {
  20:             this.Invoke(new MethodInvoker(this.Show));
  21:         }
  22:     }) 
  23:     { 
  24:         Name = "MakeInvisible (" + Duration.ToString() + ")" 
  25:     }
  26:     ).Start();
  27:  
  28: }

 

Using the lambda statement, we are providing the set of instructions to run in our new thread and using property initializers towards the bottom of the function we are setting the thread name. Closures are used with the this keyword and Duration – both of which are passing through to the lambda statement automatically from the host method (MakeInvisible).

Although a bit poor on readability, I think this is a great example of how 3.0 and threading can replace a swath of other (much more complicated) code. To write the same example without the latest language features would take at least a timer and one more method, as well as additional code to wire everything together.

 

Use Airtight Exception Handling

In production applications, it pays you to have the most extensive error handling possible in all of your worker threads. Have a look at the following unsafe code example:

   1: private void UnsafeButton_Click(object sender, EventArgs e)
   2: {
   3:  
   4:     int x = 0;
   5:     int y = 1 / x;
   6:  
   7: }

If you were to start this application outside of the debugger and press the button, at worst you would receive the following dialog box:

divide-by-zero

Bad, but life goes on (via the Continue button). Now, if that same unsafe code is put in a worker thread:

   1: private void UnsafeButton_Click(object sender, EventArgs e)
   2: {
   3:     (new Thread(()=> {
   4:         int x = 0;
   5:         int y = 1 / x;
   6:     })).Start();
   7: }

You are asking for trouble. This is what happens:

stopped-working

The entire application shuts down without details about the exception or a way to continue. (This won’t happen inside the debugger, of course). An alternative to wrapping all of your worker threads in try…catch blocks is to handle the Application.ThreadException Event. This is a quicker way to ensure that your application won’t come to grinding halt when an exception is thrown in a worker thread.

As a final note, be aware that threads are susceptible to the special exceptions ThreadAbortException and ThreadInterruptedException. It’s possible to cancel an initiated abort by handling ThreadAbortException and calling ResetAbort() in the catch block.

Share/Save/Bookmark

C#, Tips and Tricks , , , , , ,

Reference Types | Robert’s C# Musings

Archive

Posts Tagged ‘reference types’

Value Types vs. Reference Types

January 9th, 2009

One area of C# that causes confusion is the difference between value and reference types.

 

Reference Types

 

Let’s talk about reference types for a moment. A common reference type used in .NET is StringBuilder (others include Form, String, All Arrays, Classes, and Delegates). Take a look at this example, do you know what the output will be?

   1: private void Main_Load(object sender, EventArgs e)
   2: {
   3:  
   4:     StringBuilder X = new StringBuilder("It's Raining In ");
   5:     AppendCityName(ref X);
   6:     Console.WriteLine(X.ToString());
   7: }
   8:  
   9: private void AppendCityName(ref StringBuilder Source) {
  10:  
  11:     Source.Append("Seattle");
  12:  
  13: }

 

The correct answer is “It’s Raining In Seattle”. We pass our new StringBuilder into AppendCityName explicitly by reference and AppendCityName acts on the reference to the original StringBuilder. Nothing too surprising here.

 

Now try this one (I’ve taken away the “ref” keyword – resulting in X being passed By Value), what will the output be?

 

   1: private void Main_Load(object sender, EventArgs e)
   2: {
   3:  
   4:     StringBuilder X = new StringBuilder("It's Raining In ");
   5:     AppendCityName(X);
   6:     Console.WriteLine(X.ToString());
   7: }
   8:  
   9: private void AppendCityName(StringBuilder Source) {
  10:  
  11:     Source.Append("Seattle");
  12:  
  13: }

 

Did you guess “It’s Raining In Seattle”? The output is identical to the first example.

 

What’s going on here?

Did you expect the output to be “It’s Raining In ”?

StringBuilder is a reference type. That is to say, it lives on the heap (instead of the stack), and the behind-the-scenes value of X in the example above is just the address to the new StringBuilder object created on the heap.

In both examples, only the address to the original StringBuilder on the heap is being passed into the method, and even in the By Value (Second) Example, the StringBuilder data is NOT being copied or moved around at all.

There is a difference between the two, however. In the first example, both X in Main_Load() and Source in AppendCityName() point directly to the same address on the heap. In the second example, Source points to X in Main_Load(), which points to the StringBuilder on the heap.

 

Why is this important?

Passing a reference type by value or by reference is functionally the same 90% of the time. The problem is the remaining 10% of the time. Take the following example:

 

   1: private void Main_Load(object sender, EventArgs e)
   2: {
   3:  
   4:     StringBuilder X = new StringBuilder("It's Raining In ");
   5:     AppendCityName(ref X);
   6:     Console.WriteLine(X.ToString());
   7: }
   8:  
   9: private void AppendCityName(ref StringBuilder Source) {
  10:  
  11:     Source.Append("Seattle");
  12:     Source = null;
  13:  
  14: }

…which, if you were to execute, unfortunately results in…

exception-01b

Ooops. Because the StringBuilder is passed by reference, AppendCityName() is working with the original reference to the object, and not a copy of the reference. If we were passing the StringBuilder by value, this would have never happened. When in doubt, pass reference types by value and not by reference!

 

Value Types

 

Value types are the complimenting type to reference types. Instead of being stored on the heap, value types are stored on the stack (unless boxed). Integers, Booleans, and Structs are common examples of value types.

When value types are passed By Value, the actual value is copied and there are no references involved. When value types are passed By Reference, the method argument is initialized with the address pointing back to the original value in the calling routine.

 

Here’s an example of passing a value type by reference:

 

   1: private void Main_Load(object sender, EventArgs e)
   2: {
   3:  
   4:     int TotalDragonCount = 1;
   5:     IncrementDragons(ref TotalDragonCount);
   6:     Console.Write(TotalDragonCount);
   7:  
   8: }
   9:  
  10: private void IncrementDragons(ref int OriginalDragonCount) {
  11:  
  12:     OriginalDragonCount++;
  13:  
  14: }

 

The output is 2. TotalDragonCount is passed into IncrementDragons(), which properly works with a reference to the original value before exiting.

 

Here’s what happens with the same example, but missing the ref keyword (Passing By Value):

 

   1: private void Main_Load(object sender, EventArgs e)
   2: {
   3:  
   4:     int TotalDragonCount = 1;
   5:     IncrementDragons(TotalDragonCount);
   6:     Console.Write(TotalDragonCount);
   7:  
   8: }
   9:  
  10: private void IncrementDragons(int OriginalDragonCount) {
  11:  
  12:     OriginalDragonCount++;
  13:  
  14: }

The output is 1. Notice the difference between value types and reference types? If int was a reference type instead of a value type, this last example would have returned 2.

 

The Takeaway

 

Value types behave very intuitively, but be careful with reference types, especially when passing them By Reference. Know the (subtle) difference between passing value types By Reference and passing reference types By Value (A Value type passed by reference simply points back to the original value type, while a reference type by value creates a copy of the reference (address) inside the method being invoked)

Share/Save/Bookmark

C# , ,

Predicates | Robert’s C# Musings

Archive

Posts Tagged ‘predicates’

Practical Introduction to Lambda Expressions

March 31st, 2009

Lambda (11th Letter of Greek Alphabet) Popularized by Python and Ruby, the lambda expression is a powerful shorthand that can be used to significantly speed up c# development. This post deals entirely with using lambda expressions in everyday development, and sidesteps the esoteric mathematical logic that makes them intimidating.

 

Lambda What?

 

A Lambda expression in c# is simply a piece of syntactical sugar for fleshing out a function body where you would normally plug in a delegate (pointing to a function somewhere else). This saves you two or three lines of code per call, speeding up your development (where delegates are required) to light speed and making your code more maintainable.

Because lambdas can only be used where delegates are required, your initial benefit from learning them may be limited. Before looking into lambdas, I avoided using functions in the .NET base class library that required delegates because of the added hassle. Now, after learning how to use lambdas, I seek them out!

Lastly, are you familiar with anonymous methods? Lambda expressions are very similar – just a slightly shorter syntax. Anonymous methods and lambdas compile to the same intermediate language (and have the same performance as a result).

 

 

What does a lambda expression look like?

 

LambdaIdentify 

In the example above, Name => Name.StartsWith(“O”) is the lambda expression. All it does is check if the “Name” passed into it starts with a given letter and returns True/False. The Find() function (not lambda-related) runs this lambda expression against each list item until a match is found. You could use a delegate to another function (like the one below) or an anonymous method in its place, but it would be a lot more code either way.

 

This expression is roughly equivalent to the non-lambda function:

equiv 

(Which could have been plugged into FruitNames.Find() using a delegate by the way. All that was accomplished by using the lambda was saving a few lines of code.)

 

“Name”

Name is the function argument. We could have named this “FruitName”, “F”, or anything else. However, we would have had to remember to change it in the function body at the same time. Lambdas automatically infer variable types from the parent signature. In this case, StartsWith() requires a single string argument, causing “Name” to typed as a string.

 

“=>”

This is the important symbol that tells c# that you are using a lambda expression. It is absolutely required for every lambda expression that you write. Arguments go on the left and your function body goes on the right. Read as “goes to”.

 

“Name.StartsWith(“O”)”

Is plain c# and also the meat of the expression. This simply returns true if the function argument “Name” begins with the letter “O” or false if it does not. In this example, it’s only one line. However, lambdas may be expanded to multiple lines (just wrap your function body in squiggly brackets like any other method) In this case, it is required that we return a Boolean because the parent “Find()” requires a Predicate (Boolean return type):

findreq

(Predicate simply takes in one argument of a given type and returns a Boolean)

 

 

Real-World Examples

Now that you have a basic understanding of what a lambda expression is, and how it might be useful (less code), take a look at a few practical code examples.

 

Predicate Delegates

A predicate is just a function that returns true or false. Imagine helping a friend sort through a box of old items. You pick up each item out of the box and your friend (after looking at the item) either says “throw away” or “keep”. Your friend is acting as a predicate.

Predicates are extremely useful for filtering lists of items and you will find them throughout the framework for this reason. In the first example in this article we used a predicate to sort through a list of fruit by looking at the first letter of each fruit name.

Here is another example using objects instead of strings:

 

   1: private class Book
   2:  {
   3:      public string Author { get; set; }
   4:      public string Name { get; set; }
   5:      public DateTime Published { get; set; }
   6:  }
   7:  
   8:  //Create and fill a list of books
   9:  private List<Book> Books = new List<Book> { 
  10:      new Book { Author="Mcconnell",Name="Code Complete", Published=new DateTime(1993,05,14) },
  11:      new Book { Author="Sussman",Name="SICP (2nd)", Published=new DateTime(1996,06,01) },
  12:      new Book { Author="Hunt",Name="Pragmatic Programmer", Published=new DateTime(1999,10,30) },
  13:  };
  14:  
  15:  
  16:  private IEnumerable<Book> BooksPublishedAfter1995()
  17:  {
  18:      return Books.FindAll(Book => Book.Published > new DateTime(1995, 12, 31));
  19:  }

 

In this example “BooksPublishedAfter1995()” uses a lambda expression as a predicate to compare each when each book was published to a specific date. This function returns a new collection of books containing just SICP and Pragmatic Programmer.

Here’s the a similar multiline lambda that returns books published between 1991 and 1997:

 

   1: private IEnumerable<Book> BooksPublishedBetween1991and1997()
   2: {
   3:     return Books.FindAll(Book => {
   4:  
   5:         return Book.Published >= new DateTime(1991, 01, 01) &&
   6:         Book.Published <= new DateTime(1997, 12, 31);
   7:     
   8:     });
   9: }

 

As you can see, it would be excessive to type out a separate function just for this simple piece of logic. Lambda statements are ideal for this type of filtering.

 

Don’t Forget to stay DRY

(Don’t Repeat Yourself) Lambdas and anonymous methods are a power tools that should be used carefully. Remember to identify and move common predicates into shared functions early instead of using repeated Lambdas throughout your code and creating a maintenance nightmare.

 

 

Absolutely Minimalistic Threading

It is possible to spawn new threads using just the code contained in the lambda statement. In fact, you can do it in only a few lines. A good example for this is when you need to open up a webpage in the default browser from a windows forms application but don’t want the user interface to skip a beat or lock up (as is the case with some firewall software). Lambda expressions paired with a new thread will do the trick:

 

   1: (new System.Threading.Thread(()=> {
   2:  
   3:     try
   4:     {
   5:         System.Diagnostics.Process.Start("http://www.example.com");
   6:     }
   7:     catch (Win32Exception StartException)
   8:     {
   9:         //Likely caused by firewall software such as ZoneAlarm
  10:         MessageBox.Show("Failed to open URL.");
  11:     }
  12:  
  13: })).Start();

 

If you look carefully, you will notice that “()” is used on the left hand side of the lambda. This simply indicates that no arguments are to be used.

For more cool threading lambda expression examples for c#, have a look at my Threading Tips and Tricks post.

Share/Save/Bookmark

C#, Introductions , , , , ,

Overflow | Robert’s C# Musings

Archive

Posts Tagged ‘overflow’

Black Belt C# Series – Language Keywords

April 13th, 2009

The Black Belt C# series aims to uncover powerful but lesser-known features of the C# language. Each article introduces a few of these features and shows you how to use them to take your programming to the next level.

 

The “as” Keyword

The as operator is a quick way to try to cast an object to a specific type. The operator returns null if the cast fails, instead of raising an exception.

There are cases where you may have an incoming object that may be a specific type. Take a look at this X10 (home automation) example:

 

   1: private class X10Device { }
   2: private class DoorSensor : X10Device { }
   3: private class LightSwitch : X10Device { public bool On { get; set; } }
   4:  
   5: private void Controller_DeviceChangedState(X10Device Source)
   6: {
   7:     //...respond to device change based on type
   8: }

 

In this example, imagine an X10 controller is wired up to our DeviceChanged…() method and it’s called every time an x10 device changes state. Any type of X10 device could be passed into the method and we can’t be sure of the exact type of device until we check for it at runtime.

Lets say that we only want to pay attention to light switches and ignore the other device types. There are a few ways we could attempt to single out light switches and start working with them.

Here’s a traditional way of doing this:

   1: private void Controller_DeviceChangedState(X10Device Source)
   2: {
   3:  
   4:     if (Source is LightSwitch)
   5:     {
   6:         LightSwitch SourceLightSwitch = (LightSwitch)Source;
   7:  
   8:         if (SourceLightSwitch.On == true)
   9:         {
  10:             MessageBox.Show("Light Turned On!");
  11:         }
  12:  
  13:     }
  14:  
  15: }

 

This example uses the “is” keyword to single out light switches. Then it creates a new variable that is certainly a light switch and wires it up to the Source reference knowing with full certainty that the cast will succeed.

 

Here’s an alternative way to accomplish the same thing, by using the “as” keyword:

   1: private void Controller_DeviceChangedState(X10Device Source)
   2: {
   3:  
   4:     LightSwitch SourceLightSwitch = Source as LightSwitch;
   5:  
   6:     if (SourceLightSwitch != null)
   7:     {
   8:         if (SourceLightSwitch.On == true)
   9:         {
  10:             MessageBox.Show("Light Turned On!");
  11:         }
  12:     }
  13:  
  14: }

If you ask me, this example is a little bit more succinct and readable. It also neatly groups together the case for Source being null or a different type (such as a DoorSensor).

 

If you can afford a slightly lower readability, the “as” statement also allows for a more compressed syntax where the cast attempt and check are performed all on the same line:

   1: LightSwitch SourceLightSwitch = null;
   2:  
   3: if ((SourceLightSwitch = Source as LightSwitch) != null)
   4: {
   5:     if (SourceLightSwitch.On == true)
   6:     {
   7:         MessageBox.Show("Light Turned On!");
   8:     }
   9: }

 

 

The “using” Keyword

The using keyword is an unusual case of two separate (but related) keywords rolled into one name.

Aliases (the using directive)

Aliases can save you a lot of time when you have oft-used complex generics and namespaces. The using directive allows you to define the composition of these types in one place instead of typing them out over and over again. Here’s an example with nested dictionaries:

 

   1: using ComplexDictionary = Dictionary<int, Dictionary<string, List<string>>>;
   2:  
   3: public partial class Main : Form
   4: {
   5:     ComplexDictionary MainComplexDictionary = new ComplexDictionary();
   6:     ComplexDictionary SecondaryComplexDictionary = new ComplexDictionary();
   7:  
   8:     public Main()
   9:     {
  10:         InitializeComponent();
  11:     }
  12:  
  13: }

As you can see, the using directive safely abstracts the “ComplexDictionary” type to a single location and is easily readable. Changing the ComplexDictionary type would be a simple task, no matter how many times it’s used throughout the code. Furthermore, creating further new ComplexDictionary variables is now a snap. Here’s the ugly alternative:

   1: public partial class Main : Form
   2: {
   3:     Dictionary<int, Dictionary<string, List<string>>> MainDictionary = 
   4:         new Dictionary<int, Dictionary<string, List<string>>>();
   5:  
   6:     Dictionary<int, Dictionary<string, List<string>>> SecondaryDictionary = 
   7:         new Dictionary<int, Dictionary<string, List<string>>>();
   8:  
   9:     public Main()
  10:     {
  11:         InitializeComponent();
  12:     }
  13:  
  14: }

 

 

Explicit Object Scope (the using statement)

The using statement is a bulletproof way to use disposable objects. Here’s an example:

   1: using (Form NewForm = new Form())
   2: {
   3:     NewForm.Enabled = true;
   4:     NewForm.StartPosition = FormStartPosition.CenterScreen;
   5:     NewForm.Size = new Size() { Height = 100, Width = 100 };
   6:     NewForm.ShowDialog();
   7: }

In this example, a new form is created and displayed and execution blocks at ShowDialog() until the form is closed. As soon as the form is closed by the user NewForm.Dispose() is called and NewForm goes out of scope – automatically.

This is functionally equivalent to the following code:

   1: {
   2:     Form NewForm = new Form();
   3:  
   4:     try
   5:     {
   6:         NewForm.Enabled = true;
   7:         NewForm.StartPosition = FormStartPosition.CenterScreen;
   8:         NewForm.Size = new Size() { Height = 100, Width = 100 };
   9:         NewForm.ShowDialog();
  10:     }
  11:     finally
  12:     {
  13:         if (NewForm != null) ((IDisposable)NewForm).Dispose();
  14:     }
  15:  
  16:  
  17: }

The using statement makes it easy to contain object scope and ensure that objects are disposed properly every time. Taking advantage of the using statement is a great way to improve quality while not sacrificing readability.

 

The “checked” and “unchecked” Keywords

The checked and unchecked keywords are useful for controlling what happens when an arithmetic operation overflows. By default, .NET projects created in Visual Studio will allow arithmetic overflow to happen silently and without warning.

 

Default Overflow Example – Outputs “-2” with default project configuration
   1: //32,767 is the maximum value for a short 
   2: short FirstValue = 32767;
   3: short SecondValue = 32767;
   4:  
   5: //Outputs -2
   6: Debug.WriteLine((short)(FirstValue + SecondValue));

 

image Global overflow checking is not turned on by default because it’s a significant performance hit and arithmetic overflow is not really a common occurrence.

You can turn on overflow checking by opening up your project advanced build settings (left) and checking the appropriate box but it’s generally a better practice to selectively enable overflow checking instead.

These two keywords were created to give developers just that precision level of control needed over overflow checking. To use the checked keyword, simply wrap your math statement inside a “Checked { }” block.

 

Tip:

The “Checked” and “Unchecked” keywords only apply to code directly in the specified block and do not extend to arithmetic in nested function calls. Calling a function from within your checked block will not cause overflow checking to occur inside the called function.

 

Checked Overflow Example – Raises Exception
   1: //32,767 is the maximum value for a short 
   2: short FirstValue = 32767;
   3: short SecondValue = 32767;
   4:  
   5: checked
   6: {
   7:     //Raises Overflow Exception
   8:     Debug.WriteLine((short)(FirstValue + SecondValue));
   9: }

Any overflows occurring inside the parenthesis will safely raise an OverflowException, failing loudly:

 

image

 

Correspondingly, if you do enable global overflow checking, you can selectively disable it by wrapping statements inside an “Unchecked { }” block. This is especially useful for reaping performance benefits in tight loops where you can prove that overflow will not occur. Again, unchecked { } will only have performance benefits if you have manually enabled overflow checking.

Unchecked Example – Assumes global overflow checking manually enabled
   1: unchecked
   2: {
   3:     //Index will never exceed 3,276.
   4:     for (int Index = 0; Index <= 3276; Index++)
   5:     {
   6:         //Will never overflow – Index * 10 will never exceed 32,760
   7:         Debug.WriteLine((short)(Index * 10));
   8:     }
   9: }

 

 

How does overflow checking work?

Overflow checking is effectively added into your project at compile time. Turning on global overflow checking or using checked { } blocks causes the compiler to generate slightly different IL to accommodate your request. Here’s the IL from the previous example of adding two shorts:

 

Unchecked – Adds FirstValue and SecondValue
   1: .maxstack 2
   2: .locals init (
   3:     [0] int16 FirstValue,
   4:     [1] int16 SecondValue)
   5: L_0000: nop 
   6: L_0001: ldc.i4 0x7fff
   7: L_0006: stloc.0 
   8: L_0007: ldc.i4 0x7fff
   9: L_000c: stloc.1 
  10: L_000d: nop 
  11: L_000e: ldloc.0 
  12: L_000f: ldloc.1 
  13: L_0010: add 
  14: L_0011: conv.i2 
  15: L_0012: box int16
  16: L_0017: call void [System]System.Diagnostics.Debug::WriteLine(object)
  17: L_001c: nop 
  18: L_001d: nop 
  19: L_001e: ret 

 

Checked – Adds FirstValue and SecondValue with Overflow Check
   1: .maxstack 2
   2:  .locals init (
   3:      [0] int16 FirstValue,
   4:      [1] int16 SecondValue)
   5:  L_0000: nop 
   6:  L_0001: ldc.i4 0x7fff
   7:  L_0006: stloc.0 
   8:  L_0007: ldc.i4 0x7fff
   9:  L_000c: stloc.1 
  10:  L_000d: nop 
  11:  L_000e: ldloc.0 
  12:  L_000f: ldloc.1 
  13:  L_0010: add.ovf 
  14:  L_0011: conv.ovf.i2 
  15:  L_0012: box int16
  16:  L_0017: call void [System]System.Diagnostics.Debug::WriteLine(object)
  17:  L_001c: nop 
  18:  L_001d: nop 
  19:  L_001e: ret 

 

As you can see, the checked block doesn’t radically alter the output IL. Can you spot the overflow check? In the checked (second) example, the compiler emitted “add.ovf” on line 13 instead of “add”. That’s pretty much it (apart from another check on line 14 for an implicit conversion).

The special IL “add.ovf” performs an overflow check before moving the result onto the stack. Intermediate language also contains similar versions for subtraction (sub.ovf), multiplication (mul.ovf), and numeric conversion.

Share/Save/Bookmark

Black Belt, C# , , , , ,