Словарь с ключом Tuple в Powershell - PullRequest
1 голос
/ 15 января 2020

Мне нужно создать словарь с ключом Tuple в Powershell. Точно так же, как я могу сделать в C#, например:

var test = new Dictionary<(int, bool), int>();

// Add
test.Add((1, false), 5);

// Get
int a = test[(1, false)];

(взято из Hashtable с многомерным ключом в C#)

Возможно ли это? (Я использую Powershell версии 5.1.18362.145.)

Спасибо!

1 Ответ

1 голос
/ 15 января 2020

Чтобы добавить к превосходные комментарии Джероена Мостерта по этому вопросу:

Ниже приведен прямой перевод вашего C# кода в PowerShell v5. Код 1+:

using namespace System.Collections.Generic

# Construct
$test = [Dictionary[[ValueTuple[int, bool]], int]]::new()

# Add
$test.Add([ValueTuple[int, bool]]::new(1, $false), 5)

# Get
$test[[ValueTuple[int, bool]]::new(1, $false)]
  • using namespace - это функция PSv5 +, похожая на конструкцию C# using: она позволяет ссылаться на типы в указанном пространстве имен по их простым именам, без указания пространства имен.

  • Как указывает Джероен, PowerShell не имеет синтаксиса c сахара для экземпляров значений-кортежей , так что C# литерал кортежа (1, false) должен быть представлен как явный вызов конструктора:
    [ValueTuple[int, bool]]::new(1, $false).

    • Альтернативой является использование stati c Create метод базового типа non-generi c System.ValueType, в этом случае типы компонентов кортежа выводятся :
      [ValueTuple]::Create(1, $false)

Учитывая, что PowerShell предоставляет конструкторы типа с помощью метода stati c ::new() для самого типа, вы можете упрощать y код путем создания экземпляра указанного типа кортежа c один раз и повторного его использования через переменную (игнорируйте подсветку разбитого синтаксиса):

using namespace System.Collections.Generic

# Instantiate the concrete tuple type (type arguments locked in).
$tupleType = [ValueTuple[int, bool]]

# Construct the dictionary with the tuple type as the key.
# See explanation below.
$test = [Dictionary`2].MakeGenericType($tupleType, [int])::new()

#`# Add
$test.Add($tupleType::new(1, $false), 5)

# Get
$test[$tupleType::new(1, $false)]

Недостатком является то, что конструкция словаря становится более неудобной, потому что литералы типа PowerShell, такие как [Dictionary[[ValueTuple[int, bool]], int]], не должны иметь не-литеральных компонентов. Чтобы обойти это, System.Type.MakeGenericType используется для создания закрытого типа generi c из аргументов динамически определенного типа; обратите внимание на необходимость указать арность (`2) типа open generi c, для которого вызывается .MakeGenericType().

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