Click here to Skip to main content
15,881,938 members
Articles / Programming Languages / C#

Careful with Optional Arguments in C# 4.0

Rate me:
Please Sign up or sign in to vote.
4.88/5 (7 votes)
21 Feb 2011CPOL3 min read 25.8K   12   19
Careful with Optional Arguments in C# 4.0

Introduction

Some time passed since optional arguments are introduced with Visual C# 2010 and we all got used to the convenience of not having to define method overloads for every different method signature. But, recently I came across a limitation using optional arguments on enterprise solutions and now I’m using it with care.

The limitation is that if you use the optional arguments across libraries, the compiler will hard code the default value to the consumer and prevent you from re-deploying the provider library separately. It is a very common scenario on enterprise applications where we have many libraries with different versions married to each other and this limitation makes it impossible to re-deploy only one DLL without re-deploying all related libraries.

In this post, I will explain to you the details of this limitation. As I mentioned in my previous post, Under the hood of anonymous methods in C#, it is very important to know the underlying architecture of a functionality you are using. This post is similar to that by explaining mechanics of the optional arguments.

Background

I will not explain what optional arguments are, because it is already out since a while. But I will just give a quick reference to the description for those who are new to C#:

Optional arguments enable you to omit arguments for some parameters. … . Each optional parameter has a default value as part of its definition. If no argument is sent for that parameter, the default value is used. Default values must be constants.” (Named and Optional Arguments (C# Programming Guide))

I run into this limitation while I was using some functionality from a secondary library, injected through an IoC container. The secondary library was accessed through an interface where some methods had optional arguments. I had everything deployed and working until I had to make some changes to the secondary library and alter the optional argument. After re-deploying the secondary library I figured out that the changes did not take effect and when I went into the IL code I figured out that the main library had the constant hard-coded into it.

In my situation, I had interfaces, injections and a lot of complexity; to better picture the situation I will be using the simplest form of the limitation as in the following sample:

  • ProjectB has a method named Test with the following signature:
    C#
    public void Test(string arg1 = "none")
    {
    }
  • ProjectA is referencing ProjectB and using the Test method with its default argument by making the following call:
    C#
    static void Main(string[] args)
    {
    Class1 class1 = new Class1();
    class1.Test();
    }

This works very well, because ProjectA is just using arg1 value as “none”. Now let’s look at what is happening behind the scenes:

If we compile ProjectA along with ProjectB and analyze the IL code, we will see that the optional argument is nothing more than a compiler feature. Because calling Test() is no different from calling Test(“none”), the compiler decides to compile our code as Test(“none”). That can be seen in the IL code and disassembled C# code below; the string constant “none” is hard-coded into ProjectA.

MSIL
.method private hidebysig static void Main(string[] args) cil managed
{
...
L_0008: ldstr "none"
L_000d: callvirt instance void [ProjectB]ProjectB.Class1::Test(string)
...
}

private static void Main(string[] args)
{
new Class1().Test("none");
}

For libraries tightly coupled or in-library usage, it is good that the compiler helps us in eliminating some code and makes our life easier. But this comes with a price:

Let’s say we had to modify the Test method in ProjectB as Test( string arg1 = “something” ) and re-deploy it without re-deploying ProjectA. In this case, ProjectA would still be calling the Test method with “none”.

Conclusion

Knowing this, it is good to use the optional arguments with caution across libraries when you have to support deployment scenarios with partial solutions.


License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
I am an MCAD, MCSD, MCTS, MCPD, MCT and Certified CUDA Programmer.
You can find more technical articles on my blog at http://www.adnanboz.com.

Comments and Discussions

 
GeneralOptional Arguments is a dangerous feature Pin
İlkay İlknur1-Mar-11 22:45
İlkay İlknur1-Mar-11 22:45 
GeneralMy vote of 5 Pin
captnmac1-Mar-11 1:05
captnmac1-Mar-11 1:05 
GeneralInteresting Pin
EbenRoux28-Feb-11 20:20
EbenRoux28-Feb-11 20:20 
GeneralMy vote of 5 Pin
Kamran Behzad28-Feb-11 16:35
Kamran Behzad28-Feb-11 16:35 
GeneralVery useful feature that is taken from VB NET Pin
Member 381005022-Feb-11 5:47
Member 381005022-Feb-11 5:47 
GeneralRe: Very useful feature that is taken from VB NET Pin
JV999924-Feb-11 4:15
professionalJV999924-Feb-11 4:15 
GeneralRe: Very useful feature that is taken from VB NET Pin
Vozzie228-Feb-11 17:32
Vozzie228-Feb-11 17:32 
QuestionSame for const? Pin
sheitman8021-Feb-11 22:29
sheitman8021-Feb-11 22:29 
AnswerRe: Same for const? Pin
Adnan Boz22-Feb-11 7:44
Adnan Boz22-Feb-11 7:44 
GeneralRe: Same for const? Pin
Dave Shaw1-Mar-11 2:20
Dave Shaw1-Mar-11 2:20 
Yes it is and "Default values must be constants" (from your article) should be the warning indicator Smile | :)

Thanks,
Dave Shaw
History admires the wise, but elevates the brave. - Edmund Morris

GeneralMy vote of 5 Pin
Mark Lemke21-Feb-11 21:16
Mark Lemke21-Feb-11 21:16 
GeneralRe: My vote of 5 Pin
Adnan Boz22-Feb-11 7:38
Adnan Boz22-Feb-11 7:38 
GeneralMy result is totally different from yours Pin
Kevinyou21-Feb-11 19:50
Kevinyou21-Feb-11 19:50 
GeneralRe: My result is totally different from yours Pin
Adnan Boz22-Feb-11 7:43
Adnan Boz22-Feb-11 7:43 
GeneralRe: My result is totally different from yours Pin
Adnan Boz23-Feb-11 16:53
Adnan Boz23-Feb-11 16:53 
GeneralRe: My result is totally different from yours Pin
Kevinyou23-Feb-11 17:29
Kevinyou23-Feb-11 17:29 
GeneralRe: My result is totally different from yours Pin
Adnan Boz24-Feb-11 6:23
Adnan Boz24-Feb-11 6:23 
GeneralWhen you use Optional Parameter ----- Think again before leap Pin
Kevinyou24-Feb-11 19:03
Kevinyou24-Feb-11 19:03 
GeneralRe: When you use Optional Parameter ----- Think again before leap Pin
JV999924-Feb-11 20:30
professionalJV999924-Feb-11 20:30 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.