Last listened to Symphony No. 4 in G (1993 Digital Remaster): III. Ruhevoll by Paul Kletzki (on 6 Sep 2010, 05:25)

Understanding the C# var keyword

In recent weeks I have been helping my boss to recruit for new C# developers by sitting in and asking the candidates some technical questions. One of my questions was:

Can you explain to me the C# 'var' keyword?

The var keyword was introduced in C# 3.0 several years ago, so this question wasn't considered to be a modern or difficult question (such as asking for an explanation of the more recent dynamic type) - but I was surprised how many developers didn't get it right. Plus, while browsing a MonoTouch article recently, I felt compelled to reply to an ill-informed comment where someone said "var is overused. You should strongly type your variables instead." This, along with an answer a candidate gave me in a recent interview when he said "isn't the var keyword slower?" prompts me to write this post.

I would sum it up as follows: the var keyword is a shorthand way of allowing the compiler to infer the type for you - to save your fingers some work.

Some things need to be made quite clear:

  • Using var doesn't make your variables "weakly typed". All variables declared as var are strongly typed! (C# is a statically typed language - everything is strongly typed!)
  • var isn't a type. The actual type is figured out at compile-time.
  • Due to the fact that the actual types are resolved at compile-time, the var keyword cannot be "slower".
  • It sometimes increases code readability.
  • It sometimes decreases code readability.
  • It is sometimes optional, but sometimes required.

The var keyword is not a type. System.String is a type. Int32, decimal and object are types, but var is not a type. The actual type is resolved at compile-time: it is inferred based on the right-hand-side of the equals sign. Here, the variable i is strongly typed as an integer:

var i = 3;

It is identical to typing this:

int i = 3;

In both of those examples the variable i is strongly typed as an integer. Due to that fact, this will not compile:

var i = 3;
i = "foobar";

That's right, it's not a bug, it's not "sloppy coding", or an explosion at runtime: it's a compilation error. Due to the fact that the keyword var is inferred at compile-time, this statement will not compile either:

var i;

Nor will this:

var i = null;

The last one couldn't possibly compile: what if I wanted i to be an integer, then assigning null to it doesn't make sense, it would be equivalent to this statement (which also does not compile):

int i = null;

I mentioned that there are times when the var keyword can increase code readability, but also decrease it. I think there is no need for it on the first line of code in the sample below, compared with the equivalent second line:

var i = 3;
int i = 3;

My variable i is an integer, but I haven't saved myself any keyboard strokes or saved the reader some time: I think I have slightly decreased the code readability by using var. But in the example below I think that I have increased code readability on the first line, in comparison to the equivalent second line:

var config = new List<KeyValuePair<string, string>>();
List<KeyValuePair<string, string>> config = new List<KeyValuePair<string, string>>();

In the previous two examples the use of the var keyword is optional. Whether using it results in more or less readable code is a choice that the programmer must make. Using the var keyword in the example below is not optional, it is required:

var query = customers.Select( c => new { Name = c.Name } );

That was a LINQ lambda expression returning an anonymous type. The same can be expressed using LINQ's comprehension syntax:

var query = from c in customers
select new
{
Name = c.Name
};

In both of those examples, an anonymous type is being returned from the LINQ expression. Don't be fooled though: even an anonymous type is strongly typed. It is another kind of "shorthand" - instead of saying (as with the var keyword) I know the type, but I'm too lazy to write it out, with anonymous types you are saying "I know the type, but I'm too lazy to create the type myself - so I'll let the compiler do it". Due to the fact that the compiler will create the type for us, we have no option but to use the var keyword to create the type.

With a new version of C# looming - developers risk falling behind the pack if they aren't even up to speed with the current version of C#.

MonoTouch code snippet - Application Icon Badge Number

Another MonoTouch code snippet: how to set the "new items" number on your iPhone apps badge:

UIApplication.SharedApplication.ApplicationIconBadgeNumber = 11;

That will give you this result:

MonoTouch code snippet - Network Activity Indicator

The network activity indicator is in the status bar at the very top of the screen on an iPhone. You can see it just to the left of the time in this screenshot:

Network Activity Indicator in an iPhone app

In Objective-C, you can control when this is shown or not by this code:

// Show
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
// Hide
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

With MonoTouch and C# the code is almost identical:

// Show
UIApplication.SharedApplication.NetworkActivityIndicatorVisible = true;

// Hide
UIApplication.SharedApplication.NetworkActivityIndicatorVisible = false;

This is the second part of a two-part tutorial showing you how to create a simple RSS Reader application for the iPhone using C# and MonoTouch. The application will use a UINavigationController to navigate back and forth between a news list (in a UITableView) and a second view showing more details about the news article that the user selects.

In this part of the tutorial we are going to finish this app by doing the following:

  • Create a second view, which will display more information about the news article.
  • Navigate forward to that view when the user selects an item

The first thing we need to do is to create a new view. We want to show this view when the user selects a news story from the list, where we will show more information about that news story. Click File -> New File and select the "View Interface Definition with Controller" option. Name the view "DetailsViewController":

Double-click the .xib file and go into Interface Builder. Drag a UILabel onto the view, at the top. This will be for the headline, so make the font bold, a bit bigger, and allow the number of lines to be 2 or 3 (the default is 1). Then drag a UITextView onto the view, below the UILabel you just created.

Next, we need to create two outlets for these UI components we just created - it will be these outlets that we can work with in the C# code. This is done in the same way as the outlet for the UINavigationController was created in the first part of this tutorial. I have named the UILabel "headlineLabel" and the UITextView "contentTextView". When you are finished it should look like this (note, you can see the outlets are connected correctly to the UI components in the "outlets" section, at the top-right of this picture):

Save and quit Interface Builder, we are finished with it for this tutorial.

We are not quite finished with MyDetailsViewController. Open up the MyDetailsViewController.xib.cs file. We want to load this view from the XIB file when the constructor is called. We can do this by calling a base constructor, passing in the XIB file name:

public DetailsViewController() : base("DetailsViewController", null)
{
    Initialize();
}

We also want to have a public instance property of a NewsArticle in this MyDetailsViewController class, and bind the NewsArticle to the labels we created. The actual binding occurs in the ViewWillLoad method. This event gets raised just before the view loads, as the name suggests.

public NewsArticle CurrentNewsArticle;

public override void ViewWillAppear(bool animated)
{
    base.ViewWillAppear(animated);
    BindItem();
}

private void BindItem()
{
    headlineLabel.Text = CurrentNewsArticle.Headline;
    contentTextView.Text = CurrentNewsArticle.Content;
}

In the MyTableViewController.cs file, there is a class named TableDelegate which has a method called RowSelected. As the name of the method describes, this method gets called each time a row is selected in our table. At the moment we are just calling Console.WriteLine here, but instead, now we want to create an instance of our DetailsViewController and display it.

DetailsViewController detailsViewController;

public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
{
    if (detailsViewController == null)
        detailsViewController = new DetailsViewController();
				
    NewsArticle newsArticle = tvc.NewsArticles.ElementAt(indexPath.Row);
    detailsViewController.CurrentNewsArticle = newsArticle;

    tvc.NavigationController.PushViewController(detailsViewController, true);
}

Notice that I declare the detailsViewController variable on the class itself, this way I only actually instantiate it once and can reuse it each time a use clicks on a row - which will aid performance.

I fetch the NewsArticle object from the list at the row that the user clicked, then set the NewsArticle property we created earlier.

The interesting line of code is the last one: it is PushViewController that actually navigates us forward to a new view. Notice that the second parameter "true" is saying that we want this navigation process to be animated.

Once this is done we are almost there. There are only two more things that are missing: the first table view has the title "item" because we never bothered to change it when we created the table view. We can set the title in the constructor of the MyTableViewController class like this:

public MyTableViewController (IntPtr p) : base (p)
{
Title = "Tottenham News";
}

We also want the standard arrow to the right of the cell, so it looks like it is clickable. We can do this directly below the line of code where we create the UITableViewCell:

cell.Accessory = UITableViewCellAccessory.DisclosureIndicator;

Finally we are ready to build and run this application. The end result is shown below:

RSS Reader - Final result

I hope you found this tutorial helpful. Any questions or feedback are appreciated in the comments.

This is the first part of a two-part tutorial showing you how to create a simple RSS Reader application for the iPhone using C# and MonoTouch. The application will use a UINavigationController to navigate back and forth between a news list (in a UITableView) and a second view showing more details about the news article that the user selects.

In this part of the tutorial we are going to:

  • Create a UINavigationController, with a UITableViewController inside it.
  • Show a list of News Articles in the UITableView, which are taken from an RSS Feed

Firstly, create a new solution in MonoTouch called RssReader.

Create a new solution

Double-click "MainWindow.xib" which should launch Interface Builder. Our first task is to find a UINavigationController in the Library, and drag it onto the window with the title "MainWindow.xib". I recommend using the tree view mode in this window, not the icon view. After you drop your UINavigationController in there, it should look like this:

UINavigationController in your project

Once that is done, we need to create an outlet in Interface Builder, so that we can work with our UINavigationController in our C# code. To do this differs slightly depending on which version of Interface Builder you have installed, but in the latest version (at the time of writing) this is done in the Library window (it used to be done in the Inspector window). In the Library window, I need to select "Classes" at the top, then select "AppDelegate" in the list, and finally select "Outlets" at the bottom. By clicking the + button we can add a new outlet. I'm going to name it "navigationController", and once you're done you should have something looking like this:

Create an outlet for the UINavigationController

After creating the outlet, it's not actually connected to anything yet - so now we need to connect it to our UINavigationController. In the Inspector window, on the Connections tab, you should see your outlet, and an empty circle next to it, meaning it's not connected to anything yet. Drag that circle to your UINavigationController to make the connection.

Connect the outlet to the UINavigationController

Note that I'm dragging from right to left in the diagram above: connecting the outlet to the UIViewController (NOTE: I originally forgot this step in the first version of this tutorial - thanks for pointing it out Bruce).

After this is done, I'm going to find an item called UITableViewController. This is where we will display news articles that we have taken from an RSS feed. Drag it directly onto the Navigation Controller that we created earlier. You can drag it into the navigation controller in the "MainWindow.xib", or do it directly onto the designer. Once you're done with that, you should have something that looks like this:

This time, we are not going to create an outlet directly, but instead we are going to give it a class name. We haven't created this class yet, but we will do shortly. Type "MyTableViewController" into the class identity, like this:

Assign a class to the navigation controller

Remember, we haven't created this class yet, but that is our next task. For now, we are finished with Interface Builder. Save, and quit.

Okay, so now we should be back in MonoDevelop, ready to write some code. Create a C# class called "MyTableViewController.cs". This is the class that we have already told the UITableViewController to look for. I suggest you go to the Code Snack blog post on UITabBarController and add the template for a UITableViewController. Once the template is added, if you delete all of the code in a new class and type "uitvc" and click Tab on your keyboard, you end up with a standard template for a UITableViewController:

using System;
using System.Collections.Generic;
using System.Linq;
using MonoTouch.Foundation;
using MonoTouch.UIKit;

namespace RssReader
{
// [MonoTouch.Foundation.Register("MyTableViewController")]
public partial class MyTableViewController : UITableViewController
{
static NSString CellID = new NSString ("MyIdentifier");

// Constructor invoked from the NIB loader
public MyTableViewController (IntPtr p) : base (p)
{
}

// The data source for our TableView
class DataSource : UITableViewDataSource
{
MyTableViewController tvc;

public DataSource (MyTableViewController tableViewController)
{
this.tvc = tableViewController;
}

public override int RowsInSection (UITableView tableView, int section)
{
return 1;
}

public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{
var cell = tableView.DequeueReusableCell (CellID);
if (cell == null)
{
cell = new UITableViewCell (UITableViewCellStyle.Default, CellID);
}

// Customize the cell here...

return cell;
}
}

// This class receives notifications that happen on the UITableView
class TableDelegate : UITableViewDelegate
{
MyTableViewController tvc;

public TableDelegate (MyTableViewController tableViewController)
{
this.tvc = tableViewController;
}

public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
{
Console.WriteLine ("Row selected {0}", indexPath.Row);
}
}

public override void ViewDidLoad ()
{
base.ViewDidLoad ();

TableView.Delegate = new TableDelegate (this);
TableView.DataSource = new DataSource (this);
}
}
}

It's very useful to get all of that code for free. The key things to note here are:

  • There is a nested class called DataSource. This class has two important methods called RowsInSection and GetCell. We will use both of these later.
  • There is another nested class called TableDelegate. This handles things such as when the user selects a row (the RowSelected method). Later, we will navigate to another view and show details on the story that the user selected.
  • Finally, there is a method called ViewDidLoad. This will be useful, because it will be here that we will fetch the news stories from an RSS feed.

NOTE: at this point, check and see if your MainWindow.xib.designer.cs file has a partial class definition for MyTableViewController, decorated with a Register attribute. Mine did (it was generated automatically) but for some readers this didn't happen (see the comments). If not, simply decorate your MyTableViewController class with the Register attribute (it is commented out in the sample above.

If you run this app right now, it should build but you will see nothing, just an empty screen, not even our UINavigationController. That's because we haven't told it to load the navigation controller yet! If you remember, we created an outlet called "navigationController" at the start, in Interface Builder. If you go to the Main.cs file in MonoDevelop, you will see a method called FinishedLaunching. It is here that any startup views need to be added. There might already be a line commented out that does what we want. Either way, make sure we now have this code in the FinishedLaunching method:

// This method is invoked when the application has loaded its UI and its ready to run
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
window.AddSubview(navigationController.View);

window.MakeKeyAndVisible ();
return true;
}

At this point your app should run and look like this:

The app, as viewed in the simulator

This what we should expect. We can see the navigation at the top, and we can see the table in the middle, the only thing we lack is the data. Let's do that now. Firstly, create a new C# class called NewsArticle.cs like this:

using System;

namespace RssReader
{
public class NewsArticle
{
public string Headline { get; set; }
public string Content { get; set; }
}
}

Let's head back over to our MyTableViewControllerClass and get the real data and bind that to the table. Create a generic List<NewsArticle> right at the top of the class:

public partial class MyTableViewController : UITableViewController
{
List<NewsArticle> NewsArticles;
...

We will fill this list with the real data in the ViewDidLoad method. I am going to use LINQ and the System.Xml.Linq namespace here to populate the List of NewsArticles. As you can see, I have hardcoded the RSS Feed URL. I am using the BBC Tottenham Hotspur feed because that's the news I'm interested in, but you can use anything you want:

public override void ViewDidLoad ()
{
base.ViewDidLoad ();

XDocument rss =
XDocument.Load("http://newsrss.bbc.co.uk/rss/sportonline_world_edition/football/teams/t/tottenham_hotspur/rss.xml");

var query = from item in rss.Descendants("item")
select new NewsArticle
{
Headline = (string) item.Element("title"),
Content = (string) item.Element("description")
};

NewsArticles = query.ToList();

TableView.Delegate = new TableDelegate (this);
TableView.DataSource = new DataSource (this);
}

XDocument is in the System.Xml.Linq namespace - you will need to right-click of References in your project and add it. Then you will need to add a using directive at the top of your code file to that namespace, and also to System.Linq.

using System.Linq;
using System.Xml.Linq;

The RowsInSection method is currently hardcoded to "return 1" but we want it to return the dynamic length of our news article list. Let's change it to this:

public override int RowsInSection (UITableView tableView, int section)
{
return tvc.NewsArticles.Count;
}

And one final adjustment is to set the text of each cell in the table. We already have a comment that says this:

// Customize the cell here...

Change it to this:

// Customize the cell here...
NewsArticle article = tvc.NewsArticles.ElementAt(indexPath.Row);
cell.TextLabel.Text = article.Headline;

We are now finished with part 1. You can see the result here:

The final result

You can actually see slighly more than just the simulator in that last screenshot. You can also see the Application Output window. It shows that we are using Console.WriteLine to print which row was clicked when the user taps a row. This will become important in the next part of this tutorial, when instead of doing a Console.WriteLine, we will use the NavigationController to navigate forward to a new view, where the user can read more details about the news article that they selected.

Hope you liked part 1 of this tutorial and found it helpful. Head on over to part two and finish the app by navigating to a second view.

I hope you found this tutorial helpful. Any questions or feedback are appreciated in the comments.