Optional parameters and named parameters in C#4.0


If you are familiar with C++ or VB then you will already be familiar with optional parameters. They are parameters that are assigned a default value at compile time and that can be omitted when calling a method.

  public void LayoutElements(IList<Element> elements, int xOrig = 0, int yOrig = 0)
  {
    ...
  }
  
    ...

    layoutTool.LayoutElements(elementList);         // Will layout at 0, 0
    layoutTool.LayoutElements(elementList, 25, 25)  // Will layout at 25, 25

C#4.0 adds the ability to define optional parameters for methods, constructors and indexers.

An obvious area of use is constructors. Optional parameters remove the need to define multiple overloaded constructors with a variety of parameters all calling into a single constructor which does the work.

Any optional parameters must be declared after all non-optional parameters. You can overload a method to have two versions – one with an optional parameter and one without. In this case the compiler will resolve to the method without the optional parameter (following the principal of least surprise.)

    
  public void LayoutElements(IList<Element> elements)
  {
     LayoutElements(elements, 5, 5);
     ...
  }

  public void LayoutElements(IList<Element> elements, int xOrig = 0, int yOrig = 0)
  {
    ...
  }

    ...

    // Resolves to first method - will layout at 5, 5
    layoutTool.LayoutElements(elementList);

Another addition, named parameters, helps when calling a method, constructor or indexer. Similar in function to named parameters used with attributes.

You use the name of the variable to fill the parameter – using a colon to specify the value.

  // Will layout at 0, 10
  layoutTool.LayoutElements(elementList, yOrig: 10);

Named parameters can be used for both optional and positional parameters. When making the function call all named parameters must occur after any positional parameters. The named parameters do not have to appear in the order of the parameters in the method declaration.

  // Will layout at 15, 10
  layoutTool.LayoutElements(yOrig: 10, xOrig: 15, elements: elementList);

If you use partial methods, then for both optional and named parameters the declaration in the definition is used at compile time.

  partial void LayoutElements(IList<Element> elements, int xOrig = 0, int yOrig = 0);

   ...

  partial void LayoutElements(IList<Element> elements, int x = 5, int y = 5)
  {
    ...
  }

    ...

//    layoutTool.LayoutElements(elementList, y : 10);    // Will not compile
    layoutTool.LayoutElements(elementList, yOrig : 10);  // Will layout at 0, 10

Be aware that if you rename parameters in a method that is called elsewhere with the named parameter syntax, then the names will no longer match and the calling code will not compile.

Advertisement

Update UI from background worker thread without explicit marshalling


It is possible to update the UI thread from a background worker thread without the need to explicitly marshal the call across to the UI thread. An example follows.

A separate blog entry details how to update a UI using explicit marshalling.

The background worker member is used to perform potentially long lasting non-UI activities:

    private BackgroundWorker m_bw = new BackgroundWorker();

When starting the background worker (e.g. in the instance constructor after InitializeComponents for a WPF application) set the flag to indicate that the worker reports progress and add a ProgressChangedEventHandler:

    m_bw.DoWork += bw_DoWork;
    m_bw.WorkerReportsProgress = true;
    m_bw.ProgressChanged += bw_ProgressChanged;
    m_bw.RunWorkerAsync();

In the background worker activity when you want to update the UI call the ProgressChanged method on the background worker using the overload to pass a state object:

    int progress = 50;
    var state = new KeyValuePair<string, string>("Status", "Still working");
    m_bw.ReportProgress(progress, state);

The event that this call raises is raised on the thread that created the background worker – so in this case the UI thread – which means that implicit marshalling has occurred. In the ReportProgressEventHandler you can then directly update the UI controls:

    void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        ...

        var state = (KeyValuePair<string, string>) e.UserState;
        m_xamlProgress.Text = e.ProgressPercentage + "%";
        m_xamlStatus.Text = "Status: " + state.Value;

        ...
    }

This approach separates the creation of the update data from the activity of updating the controls – providing an implicit interface between the worker thread and the UI thread.

In more complex scenarios where threads that have not been created by the UI thread need to update controls the mechanism of Control.InvokeRequired followed by use of Invoke / Dispatcher can be used.

Software expansion


I have often thought that identifying and exploring a new idea within software is like discovering a new bubble of understanding.  The rush of first identification of the idea is followed by a phase of exploration of the extent and internal structure of the idea – the expansion phase.  It does not matter if the idea has been had by someone before – if it is your first encounter with the idea, then it is all new.  It is all good.

After a while you may start to consider the value and facility of the idea and the means by which you would go about implementing it.  Implementation needs impose a framework that  does not necessarily represent the natural structure of the idea, but defines how it would be possible to engineer the idea using the tools that you know.

To me this highlights one of the great benefits of managed software environments like .Net and Java.  The richness of the framework and the wide availability of tools and libraries enable you to focus on the idea at hand, rather than preliminary work building a supporting infrastructure.

Once the software idea has been implemented, it is often difficult to communicate the newness of the idea to new developers joining the project.  This may be due to the fact that the idea is communicated in terms of the implementation frameworks that have been imposed on the idea – which are just projections of the idea onto known tools, techniques and choices.

Spring clean your usings


If you have worked on software that has been extended, upgraded and re-factored over time – then you will be aware that using statements accumulate at the top of C# files.  Some of these will be for namespaces and types that are no longer used in the code below.

An addition to the Visual Studio 2008 IDE is the ability to clean up and organise these using statements.

Just right-click to get the context menu in your code files and you will see the new menu option “Organize Usings”.  With this you can remove usings that are no longer in use, or sort the usings for a more aesthetic list.  Or why not go for a full clean up and do both!

A cup of coffee


Software is a wonderful innovation.  There are many languages and frameworks out there that allow developers to express themselves in a simple and elegant way.

This blog will focus on some of these languages and frameworks and bring to light interesting, complex or just good to know features and capabilities.  Articles will range from simple and accessible for beginners up to whatever can be imagined.

Welcome!  I hope you enjoy the ride.