Frank Puffer
Frank Puffer

Reputation: 8215

Immutable local values in c# - a specific use case

I know that this general topic has been discussed here before. What I am interested in is if there is a good solution for my specific case:

I have a command line tool like this (simplified):

static void Main(string[] args)
{
    if (args.Length < 2)
    {
        Console.WriteLine("Usage: MyTool <InputFolder> <OutputFolder>");
        return;
    }

    string inputFolder = args[0];
    string outputFolder = args[1];

    // ...
}

I assign names to the argument values to make the code more readable. I would also like to express that these values will not be modified later.

Neither const nor readonly can be used here because the values is not known at compile time and because they are local 'variables' and not class members.

So how could I make this code more expressive and readable?

Upvotes: 4

Views: 555

Answers (5)

Fabio
Fabio

Reputation: 32445

You are talking about local variables.
string is already immuttable type. Values of inputFolder and outputFolder will never changes. Of course you can assign new values to it, but you are inside one method, how big this method should be that you forget to not assign new values to it.

If values are going to be passed to other methods, they will be passed as copies, so what happen inside a method will not affect actual values of inputFolder and outputFolder.

If you still insist to have those values immutable, than consider using of types designed to be immutable.

Value tuples

(Input string, Output string) folders = (args[0], args[1]);

// Usage
folders.Input
folders.Output  

Or immutable dictionary (requires System.Collections.Immutable NuGet package)

var folders = 
    new ImmutableDictionary<string, string>().Add("input", args[0])
                                             .Add("output", args[1]);

// Usage
folders["input"]
folders["output"]

Upvotes: 0

Magnus
Magnus

Reputation: 46929

How about the C# 7.2 ref readonly?

static void Main(string[] args)
{
    if (args.Length < 2)
    {
        Console.WriteLine("Usage: MyTool <InputFolder> <OutputFolder>");
        return;
    }

    ref readonly var inputFolder = ref args[0];
    ref readonly var outputFolder = ref args[1];
}

Upvotes: 2

Antoine V
Antoine V

Reputation: 7204

My proposition is creating a class holding your variables

public class Immutable
{
    public Immutable(string[] args)
    {
         InputFolder = args[0];
         OutputFolder = args[1];
    }
    public readonly string InputFolder;
    public readonly string OutputFolder;
}

then

var m = new Immutable(args)

Upvotes: 3

Victor Procure
Victor Procure

Reputation: 883

I'd do something like this:

public class ImmutableObject
{
    public ImmutableObject(string inputFolder, string outputFolder)
    {
        InputFolder = inputFolder;
        OutputFolder = outputFolder;
    }

    public string InputFolder {get;}
    public string OutputFolder {get;}
 }

static void Main(string[] args)
{
    if (args.Length < 2)
    {
        Console.WriteLine("Usage: MyTool <InputFolder> <OutputFolder>");
        return;
    }

    var folders = new ImmutableObject(args[0], args[1]);

    // ...
}

Upvotes: 1

Ryan Pierce Williams
Ryan Pierce Williams

Reputation: 1004

You could create some sort of Inputs class where you could parse the array into its parts and make the properties that expose the parsed values readonly. Simple Example:

public class Inputs {
    private string[] _args;

    public string InputFolder { get { return _args[0]; } }
    public string OutputFolder { get { return _args[1]; } }

    public Inputs(string[] args) { _args = args.Clone(); }

}

Upvotes: 1

Related Questions