‘Programming’ Category Archives
Apr
Option type implementation in C#
by Mikael Lundin in F#, Programming
F# has this clever functionality called Option<’a>. This means that, instead of returning null from a function, you return an option. This option could have the value Some x or None, where x is the value you want to return, clearly indicating that this method could return a value or not.
let getIndexOfSubstring (s : string) (substring : string) =
let index = s.IndexOf(substring)
match index with
| -1 -> None
| n -> Some n
Function signature:
val getIndexOfSubstring : string -> string -> int option
And for those of you not fluent in F#, this means that getIndexOfSubstring takes two strings and returns an option of int. This option could be Some int, or it could be None if the substring is not found.
What you win, is that option is now part of the method signature. As a method invoker you will have to handle the None option. As with NULL references, a null return value is often a side effect of the method and often unexpected.
Implement Option<’a> in C#
The option type is a type that we use as return value from a method.
public Option<int> GetIndexOfSubstring(string s, string substring)
{
var index = s.IndexOf(substring);
if (index == -1)
return new None<int>();
return new Some<int>(index);
}
What does this mean?
- The implementation clearly states that the method returns some value or no value at all.
- If the return type is an option, you need to return both Some and None for the construct to be valid. The caller of this method expects that both Some and None are possible values.
The method signature also provides you with better test names.
[Test]
public void ShouldReturnSomeIndexForExistingSubstring()
{
/* Test implementation */
}
[Test]
public void ShouldReturnNoneWhenSubstringDoesNotExist()
{
/* Test implementation */
}
What are Some and None?
The example code makes much more sense if you look at the class diagram of Some/None.
The code for the option is very abstract.
// Used as return type from method
public abstract class Option<T>
{
// Could contain the value if Some, but not if None
public abstract T Value { get; }
public abstract bool IsSome { get; }
public abstract bool IsNone { get; }
}
We could implement IsSome/IsNone by comparing this type with Some/None class, but I don’t like the idea of a superclass reference any subclass.
The implementation of Some and None are pretty straight forward.
public sealed class Some : Option
{
private T value;
public Some(T value)
{
// Setting Some to null, nullifies the purpose of Some/None
if (value == null)
{
throw new System.ArgumentNullException("value", "Some value was null, use None instead");
}
this.value = value;
}
public override T Value { get { return value; } }
public override bool IsSome { get { return true; } }
public override bool IsNone { get { return false; } }
}
public sealed class None : Option
{
public override T Value
{
get { throw new System.NotSupportedException("There is no value"); }
}
public override bool IsSome { get { return false; } }
public override bool IsNone { get { return true; } }
}
Creating a Some instance with null value is only ridiculous, and that is why we throw an exeption. The same goes for calling Value on None.
How do you call a method that returns Option<T>?
Here is some code that will call my first example and act differently if the result is Some or None.
// Get string before substring
private string SubstringBefore(string s, string substring)
{
var operations = new StringOperations();
var index = operations.GetIndexOfSubstring(s, substring);
if (index.IsSome)
return s.Substring(0, index.Value);
return s;
}
What are the benefits of the calling method?
- The result must immediately be checked if it is Some/None before you start using the value. Of course you could ignore the check and go directly to index.Value if you’re willing to take the exception when index is None. (just like null values)
- It’s clear for the reader that GetIndexOfSubstring might not return a value and that has to be dealt with.
Using Option<T> with reference types
Value types like int already have this functionality with Nullable<T>. Nullable works the same way with a different purpose, to give value types a null value.
With value types it is quite clear that “null” means “no value”, but with reference types it could mean
- Abscense of value. The method states that for given input there is no output value.
- Empty set. Specially working with databases, null could mean that the result set was empty.
- Unknown. The method does not know how to respond and throw us a null (when it really should throw an exception)
- Not initialized. An object has not been initialized and the reference is null.
The real danger of null in .NET is when it comes from the framework or a third part library and we where not expecting it. That is when you’ll see the NullReferenceException, the most – and it could pop up at any time in production.
This is why we don’t allow null values into Some. Better to fail early when we’re creating the result set of the method, than letting the program run in a faulted state until it tries to use that value.
public Option<User> FindUserByName(string name)
{
var query = from user in Users
where user.FirstName.Contains(name) || user.Surname.Contains(name)
select user;
var found = query.FirstOrDefault();
if (found == null)
return new None<User>();
return new Some<User>(found);
}
What has to be noticed in this example, is that found really have to be checked for null before entered into Some, or it may blow up. This means that Some/None null checks would be all over the place violating DRY. Could we fix it with an extension method?
public static class OptionExtensions
{
public static Option<T> SomeOrNone<T>(this T reference)
where T : class
{
if (reference == null) return new None<T>();
return new Some<T>(reference);
}
}
And this changes the previous example to.
var found = query.FirstOrDefault(); return found.SomeOrNone();
When is it elegible to return Some<T> instead of Option<T>?
When we have a reference return type that we want to communicate, “could never be null”, we could use Some as the return type, but this would feel a bit weird at the method invokers end.
You could communicate the same thing with Microsoft Code Contracts.
Here’s really three possible state of Option<T>, Some/None and Null. How do I protect myself from a method with Option<T> return type, from returning null?
Microsoft Code Contracts is also the answer here, or you could look into AOP and write an aspect that will throw an exception when you try to return null instead of an instance of Option<T>.
If you’ve decided on the method signature, you probably also agree on the pattern Some/None. But the method signature could be forced upon you with an interface, and in that case some security measure that makes sure that you don’t return null could be useful.
All the source code in a nice packaged VS2010 solution can be downloaded from here.
Apr
Zune software is not launched. Retry after making sure that Zune software is launched
by Mikael Lundin in Programming
I was getting started with some WP7 development today, but already on my first Compile/Run i ran into this error message. “Zune software is not launched. Retry after making sure that Zune software is launched.”
After some googling I found out that the default target after installing Zune with a real phone would be to run the project on the phone. Not interesting for me, while in this early stages of development. I want to run my project in the emulator.
Some more googling and I found out that there’s an option in the “Standard toolbar” where you can choose target. Not very obvious to me as I’ve removed all my toolbars to free up some screen space. A prime example on how non-default GUI options could backfire.
Enabling the “Standard toolbar” and changing the run target, did the trick.
Mar
56 useless buttons in your IDE
by Mikael Lundin in Programming
When did you last click a button in those toolbars in Visual Studio? Been a while, huh? Isn’t it time to give that space over to more code screen space?
You simply remove the toolbars by right click and deselect all checked. Don’t worry, you’re already using keyboard shortcuts for those things that you have up there. And if not .. here’s a short reminder.
Standard toolbar
| # | Name | Keyboard shortcut |
|---|---|---|
| 1 | New Project | Ctrl + Shift + N |
| 2 | Add New Item | Ctrl + Shift + A |
| 3 | Open File | Ctrl + O |
| 4 | Save File | Ctrl + S |
| 5 | Save All | Ctrl + Shift + S |
| 6 | Cut | Ctrl + X |
| 7 | Copy | Ctrl + C |
| 8 | Paste | Ctrl + V |
| 9 | Undo | Ctrl + Z |
| 10 | Redo | Ctrl + Y |
| 11 | Navigate Backward | Ctrl + - |
| 12 | Navigate Forward | Ctrl + Shift + - |
| 13 | Start Debugging | F5 |
| 14 | Solution Configurations | |
| 15 | Find in Files | Ctrl + Shift + F |
| 16 | Find | Ctrl + “ |
| 17 | Solution Explorer | Ctrl + W, S |
| 18 | Properties Window | Ctrl + W, P |
| 19 | Team Explorer | Ctrl + W, M |
| 20 | Object Browser | Ctrl + W, J |
| 21 | Toolbox | Ctrl + W, X |
| 22 | Start Page | |
| 23 | Extension Manager | |
| 24 | Command Window (other windows) | Ctrl + W, A |
Build toolbar
| # | Name | Keyboard shortcut |
|---|---|---|
| 25 | Build Project | Shift + F6 |
| 26 | Build Solution | F6 |
| 27 | Cancel | Ctrl + Break |
Debug toolbar
| # | Name | Keyboard shortcut |
|---|---|---|
| 28 | Start Debugging | F5 |
| 29 | Break All | Ctrl + Alt + Break |
| 30 | Stop Debugging | Shift + F5 |
| 31 | Restart | Ctrl + Shift + F5 |
| 32 | Show Next Statement | Alt + Num * |
| 33 | Step Into | F11 |
| 34 | Step Over | F10 |
| 35 | Step Out | Shift + F11 |
| 36 | Search for this line in IntelliTrace | |
| 37 | Hexadecimal Display | |
| 38 | Show Threads in Source | |
| 39 | Breakpoints | Ctrl + D, B |
Text toolbar
| # | Name | Keyboard shortcut |
|---|---|---|
| 40 | Display Object Member List | Ctrl + K, L |
| 41 | Display Parameter Info | Ctrl + K, P |
| 42 | Display Quick Info | Ctrl + K, I |
| 43 | Display Word Completion | Ctrl + K, W |
| 44 | Toggle Suggestion And Standard Completion Mode | |
| 45 | Decrease Indent | Shift + Tab |
| 46 | Increase Indent | Tab |
| 47 | Comment Out Selection | Ctrl + K, Ctrl + C |
| 48 | Uncomment Selection | Ctrl + K, Ctrl + U |
| 49 | Display Quick Info | Ctrl + K, I |
| 50 | Toggle Bookmark | Ctrl + B, T |
| 51 | Goto Previous Bookmark | Ctrl + B, P |
| 52 | Goto Next Bookmark | Ctrl + B, N |
| 53 | Goto Previous Bookmark in Folder | |
| 54 | Goto Next Bookmark in Folder | |
| 55 | Goto Previous Bookmark in document | |
| 56 | Goto Next Bookmark in document | |
| 57 | Clear All Bookmarks | Ctrl + B, C |
And remember, you can change any keyboard shortcut that you’re not comfortable with.
Mar
Mar
Custom ConfigurationSection from System.Configuration
by Mikael Lundin in Programming
Sometimes we forget about System.Configuration. This is plain when you find a project with its custom configuration xml parsing techniques. Maybe we all need to be reminded about System.Configuration.
Say you want configuration that looks like this.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="fileCopy" type="LiteMedia.ExampleConfiguration.Configuration.SectionHandler, LiteMedia.ExampleConfiguration"/>
</configSections>
<fileCopy>
<source>
<directory path="C:\Temp1" />
<directory path="C:\Temp2" />
</source>
<destination>
<directory path="D:\Temp1" />
<directory path="D:\Temp2" />
</destination>
</fileCopy>
</configuration>
Let’s start by the inner most element, directory. This is a class that inherits from System.Configuration.ConfigurationElement. Each property decorated with the ConfigurationPropertyAttribute is an attribute on the configuration element.
public class Directory : ConfigurationElement
{
private const string PathIdentifier = "path";
[ConfigurationProperty(PathIdentifier)]
public string Path
{
get { return (string)this[PathIdentifier]; }
set { this[PathIdentifier] = value; }
}
}
We need a configuration element that can hold a list of other configuration elements. This needs to inherit from System.Configuration.ConfigurationElementCollection. There are some more work involved telling the collection what inner element to expect.
[ConfigurationCollection(typeof(Directory),
CollectionType = ConfigurationElementCollectionType.BasicMap,
AddItemName = AddItemNameIdentifier)]
public class Directories : ConfigurationElementCollection
{
public const string AddItemNameIdentifier = "directory";
public override ConfigurationElementCollectionType CollectionType
{
get { return ConfigurationElementCollectionType.BasicMap; }
}
protected override string ElementName
{
get { return AddItemNameIdentifier; }
}
public void Add(Directory directory)
{
BaseAdd(directory);
}
protected override ConfigurationElement CreateNewElement()
{
return new Directory();
}
protected override object GetElementKey(ConfigurationElement element)
{
var instance = (Directory)element;
return instance.Path;
}
}
Finally we can create the holder element, the ConfigurationSection. We reference the section from the <configSection> in the App.config file and from here we reach the rest of the configuration. Our configuration section is very simple.
public class SectionHandler : ConfigurationSection
{
private const string SourceIdentifier = "source";
private const string DestinationIdentifier = "destination";
[ConfigurationProperty(SourceIdentifier)]
public Directories Source
{
get { return (Directories)this[SourceIdentifier]; }
set { this[SourceIdentifier] = value; }
}
[ConfigurationProperty(DestinationIdentifier)]
public Directories Destination
{
get { return (Directories)this[DestinationIdentifier]; }
set { this[SourceIdentifier] = value; }
}
}
Some test program to make sure that it works.
public static void Main(string[] args)
{
var configuration = (SectionHandler)ConfigurationManager.GetSection("fileCopy");
Console.WriteLine("SOURCE DIRECTORIES");
foreach (Directory directory in configuration.Source)
{
Console.WriteLine(directory.Path);
}
Console.WriteLine("DESTINATION DIRECTORIES");
foreach (Directory directory in configuration.Destination)
{
Console.WriteLine(directory.Path);
}
Console.ReadLine();
}
You can download the code sample as a zip archive from here.









