Showing posts with label Optional Parameter. Show all posts
Showing posts with label Optional Parameter. Show all posts

Friday, January 22, 2016

C# Interfaces and Default Parameters

How does a default parameter work?

One of the things that I love about C# is how so many of it's features are just very conveniently designed compiler tricks. This means that, just like any other magic trick, once you know how the trick is performed you immediately realize that there is nothing magical about it all!

So, let's talk about default parameters. They are actually just constant values that get compiled into your code when you go to use a method that has them. Let's look at an example...

public class DefaultParamTests1
{
    [Fact]
    public void WhatYouWrite()
    {
        var actual = Double();
        Assert.Equal(2, actual);
    }
 
    private static int Double(int i = 1)
    {
        return i * 2;
    }
}
 
public class DefaultParamTests2
{
    [Fact]
    public void WhatItCompilesTo()
    {
        var actual = Double(1);
        Assert.Equal(2, actual);
    }
 
    private static int Double(int i)
    {
        return i * 2;
    }
}

What happens when interfaces and methods don't match?

So, now that you know how the trick is performed, what happens if you use a different default value for a parameter defined by an interface and a class?

The answer is simple: if your object is cast as the class, then it will use the class value. If your object is cast as the interface, it will use the interface value instead. Let's take a look at another example...

Saturday, August 22, 2015

Ambiguous Invocation from Optional Parameter Overloads

There are many reasons for your C# compiler to give you an ambiguous invocation error. When using optional arguments you have to be sure not to create an overload that have overlapping optional parameters. Let's take a look:

public void DoStuff(int i, object o = null) { }
 
public void DoStuff(int i, string s = null) { }
 
public void DoStuff(int i, string s = null, bool b = false) { }
 
public void Test()
{
    // Ambiguous invocation!
    DoStuff(1);
}

There is no need to create methods like the ones shown above!

Instead consider that there is no reason to have two overloads being called with the potentially the same parameters. Such overloads should be combine into one method, and other overloads with different types argument can just be written as normal parameters without default values. Again, let's take a look:

public void DoStuff(int i, object o) { }
 
public void DoStuff(int i, string s = null, bool b = false) { }
 
public void Test()
{
    // No more ambiguous invocation :)
    DoStuff(1);
}

I hope that helps,
Tom

Real Time Web Analytics