Неизменные локальные значения в C # - конкретный случай использования - PullRequest
0 голосов
/ 09 ноября 2018

Я знаю, что эта общая тема обсуждалась здесь ранее. Меня интересует, есть ли хорошее решение для моего конкретного случая:

У меня есть такой инструмент командной строки (упрощенно):

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

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

    // ...
}

Я присваиваю имена значениям аргумента, чтобы сделать код более читабельным. Я также хотел бы выразить, что эти значения не будут изменены позже.

Ни const, ни readonly не могут использоваться здесь, потому что значения не известны во время компиляции и потому что они являются локальными «переменными», а не членами класса.

Так, как я мог сделать этот код более выразительным и читабельным?

Ответы [ 5 ]

0 голосов
/ 24 января 2019

Вы говорите о локальных переменных.
string - это уже неизменный тип. Значения inputFolder и outputFolder никогда не изменятся. Конечно, вы можете присвоить ему новые значения, но вы находитесь внутри одного метода, насколько большим должен быть этот метод, чтобы вы забыли не назначать ему новые значения.

Если значения будут переданы другим методам, они будут переданы как копии, поэтому то, что происходит внутри метода, не повлияет на фактические значения inputFolder и outputFolder.

Если вы все еще настаиваете на том, чтобы эти значения были неизменяемыми, тогда рассмотрите возможность использования типов, разработанных как неизменяемые.

Значение кортежей

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

// Usage
folders.Input
folders.Output  

Или неизменный словарь (требуется пакет System.Collections.Immutable NuGet)

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

// Usage
folders["input"]
folders["output"]
0 голосов
/ 09 ноября 2018

Как насчет 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];
}
0 голосов
/ 09 ноября 2018

Мое предложение - создать класс, содержащий ваши переменные

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

затем

var m = new Immutable(args)
0 голосов
/ 09 ноября 2018

Я бы сделал что-то вроде этого:

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]);

    // ...
}
0 голосов
/ 09 ноября 2018

Вы можете создать какой-то класс Inputs, где вы сможете разобрать массив на его части и сделать свойства, которые предоставляют проанализированные значения, только для чтения.Простой пример:

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(); }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...