Question

I am using the new .Net 4.5 feature for specifying Optional parameters as an OptionalAttribute (see MSDN) in the method signature like so.

public void GenerateReport(int ReportId, [Optional] string saveToFolderPath)

This works fine.

If the optional saveToFolderPath parameter is not passed, I want to set the value of saveToFolderPath to the current working directory using the static method Directory.GetCurrentDirectory.

When I try to type that, I get the following warning / error.

An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type

How To Set OptionalAttribute of Optional Parameter In C#

So are my options restricted to inspecting if the saveToFolderPath parameter is null or empty inside the method, and not in the signature itself?

In other words, my question is, How do I Set the value of an Optional Parameter that uses the OptionalAttribute syntax, to The Current Directory?

Was it helpful?

Solution

You can't. An optional parameter's default value is stored in IL as a constant. "The current directory" is not a constant, so it can't be used as a default value.

The closest you can easily come is to make the optional value null, and use the current directory in that case:

// Use the C# syntax for this, rather than specifying the attribute explicitly
public void GenerateReport(int ReportId, string saveToFolderPath = null)
{
    saveToFolderPath == saveToFolderPath ?? Directory.GetCurrentDirectory();
    ...
}

I don't think there's anything you can do explicitly using attributes that you can't do using the C# syntax for optional parameters, so you might as well be idiomatic about it.

That does mean that anyone explicitly passing null will get the same behaviour, however - which may not be what you want. Another alternative is to use two overloads as Servy has shown.

OTHER TIPS

If you want the default value of an option parameter to be a non-compile time constant, then you'll need to use method overloading instead:

public void GenerateReport(int ReportId)
{
    GenerateReport(ReportId, Environment.CurrentDirectory);
}
public void GenerateReport(int ReportId, string saveToFolderPath)
{
}

The advantage of using .NET OptionalAttribute class is that OptionalAttribute parameters do not require a default value - Note The code which explains how to solve your case is below:

namespace OptionalAttributeDirectory
{
    class Program
    {
        static void Main(string[] args)
        {
            //Calling the helper method GenerateReport only with required parameter
            GenerateReport(1);
            //Calling the helper method GenerateReport with required and optional parameters
            GenerateReport(1, @"C:\");
        }

        public static void GenerateReport(int ReportId, 
            [System.Runtime.InteropServices.OptionalAttribute] string saveToFolderPath)

        {

            if (saveToFolderPath == null)
            {
                saveToFolderPath = System.IO.Directory.GetCurrentDirectory();
            }
            Console.WriteLine("The report - " + ReportId + 
                  " saved in the folder " + saveToFolderPath);
        }
    }
}

In this code, the helper method is possible to call without the optional parameter and it means that it is more effective than method when the optional parameter must be included and it value must be set to null.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top