Showing posts with label c#. Show all posts
Showing posts with label c#. Show all posts

Wednesday, 11 September 2013

Ref keyword example in C# with structs

In C# if you define a class, then an instance of that class is passed around by reference as it is a reference type.


The above code shows a class called 'Range' which has two int properties, X and Y.

However, if you are familiar with Mircrosoft's suggestions for when to use a struct, you might realise that we should use it here. Microsoft say that a struct should have all of the following characteristics:

  • It logically represents a single value, similar to primitive types (int, double, etc)
  • It has an instance size under 16 bytes (remember that an int is 4 bytes)
  • It is immutable
  • It will not have to be boxed frequently
Ok so let's define our Range.cs as a struct instead.  All that we need to do is change the keyword 'class' to 'struct'.

Easy peasy. 

Struct defines a value type and so instance of our range object will be passed around by value instead of by references. 

[Note: 
Passing by value: When the object itself is passed around
Passing by reference: Passing a reference to the object in memory]

To illustrate this point imagine that we have 2 move methods, one that takes in a Range and one that takes in a StructRange and moves them diagonally upwards to the right.

Now let's calls these methods:

The output is the following:

          [Range: X=1, Y=1]
          [Range: X=2, Y=2]
          [StructRange: X=1, Y=1]
          [StructRange: X=1, Y=1]

What what? It worked on the range object and moved the coordinates from (1,1) to (2,2) but on the structRange object nothing changed.

When the Move method was called with the structRange, the method was passed copies of the values 1 and 1.  It incremented those values, but the original objects were untouched. To fix this, we need to pass a reference to the struct object to the Move method.  Then the method goes and looks in memory for the ints stored at that memory location and increments them.

Passing by references is shown in the following snippet:

The output is then correct; the move method has been applied:

          [StructRange: X=1, Y=1]
          [StructRange: X=2, Y=2]

Best Practices for using var in C#

Var was introduced in version 3 of C# and Resharper was updated such that now, any time you don't use a var, Resharper shouts at you and highlights the offending line by underlining it in a squiggly green line.




However, sometimes C# developers can get a little bit 'var happy' and turn everything into a var, which isn't always a good idea.  The most 'non-functional requirement', if you will, that a developer should fulfil is to produce code that is readable and easy for another person to understand quickly.  The extra minute or two it takes to understand a simple line of code may seem like nothing, but if this extra time is required to understand a whole chunk of code the time adds up.

Here are a few examples of when and when not to use var.

Example 1


Consider the following code:

Dictionary<string, List<Person>> myDictionary = new Dictionary<string, List<Person>();

Talk about LONG WINDED.  This is clearly a good candidate for var.

                      var myDictionary = new Dictionary<stringList<Person>();

I think we all agree that it it obvious what time the variable 'myDictionary' is.

Example 2

var hobby = person.Hobbies.First("baseball");

This is slightly more ambiguous that the previous example.  What are we returning? Is is perhaps an object of type 'Hobby' or maybe 'IHobby' or what about 'Baseball'?  It is obvious that we are returning something to do with someone's hobby but without knowing the codebase or going and looking inside the Person class we don't know what object we are dealing with.

If there are a string of method calls then avoid assigning the result to a var.

Example 3

var i = 1;
var s = "hiya";

Apart from the fact that I think that 1-character variable names are of the devil (except inside a loop) this is fine. It is obvious that these are an int and string respectively.

Summary

In general, follow your instincts.  I think it is far worse to write ambiguous code overusing var that to be a bit long winded and spell everything out.

It is also worth mentioning that if you are using var, it is generally a good idea to make sure that your variables are named appropriately (though of course you should be doing this anyway regardless of whether or not you are using var :) ). 

A short introduction to delegates in C#

Imagine that you have some code that iterates over a list of ints and prints them.

Now, suppose that you decide that you want your display method to display them in a different way.  You actually want to write your list to a file rather than printing to the console, but you need to be backwards-compatible, so you need to retain the ability to simply print to console.

The first thing that you think of might be to create some sort of Handler object and call the equivalent of the handler.handle() method on it (this is essentially the strategy pattern, if you are interested). This is shown in the following example:

We have classes implementing the IDisplayHandler interface which display objects in different ways.

Example usage is shown below:

Lovely, you say.  Where on earth do delegates come into this?  Well, in C# you can use delegates to do make this solution much simpler.

Introduction to Delegates


Essentially, a delegate is a type which defines a method signature. An instance of a delegate can point to any method with the corresponding signature and delegates are used to pass around methods as parameters.

For example:

public delegate int ExecuteCalculation(int x, int y); 

This defines a method signature which takes in two ints and returns one int. Let's understand this more clearly with a simple example based on our strategy pattern display example above.

Simple Delegate Example


Define a delegate using the delegate keyword.

 private delegate void DisplayIt(object o); 

This delegate will need to point to a method which takes in any object and returns void.

I know a method like this! The plain old Console.WriteLine().

var display = new DisplayIt(Console.WriteLine());

All that remains is to pass it into the Display method which, instead of calling Console.Writeline() explicitly will simply pass the objects to the delegate which in turn calls its 'Invoke' method and VOILA, you have printed to the console.  

The example below shows the complete code:






Scala with Cats: Answers to revision questions

I'm studying the 'Scala with Cats' book. I want the information to stick so I am applying a technique from 'Ultralearning...