Подтвердить что ты не робот

Использование тернарного оператора: "только назначение, вызов, приращение..."

У меня есть словарь действий, который определяется как:

var actions = new Dictionary<string, Action<string, string>>();

Я помещал туда такие действия, как:

actions.Add("default", (value, key) => result.Compare(value, properties[key], Comparers.SomeComparer, key));
...

Я использую этот код для его запуска:

if (actions.ContainsKey(pair.Key))
{
    actions[pair.Key](pair.Value, pair.Key);
}
else
{
    actions[""](pair.Value, pair.Key);
}

Это работает отлично, но я хотел использовать '?' обозначение, чтобы сделать его короче:

actions.ContainsKey(pair.Key) ? actions[pair.Key](pair.Value, pair.Key) : actions[""](pair.Value, pair.Key);

Этот код показывает мне ошибку:

Ошибка 1 Только назначение, вызов, приращение, декремент и новый объект выражения могут быть использованы как Заявление

actions[pair.Key](pair.Value, pair.Key) не вызов? Я что-то упустил? Можно ли использовать '?' обозначение с помощью словарей действия? Я пытался найти что-то по этому поводу, но трудно найти что-нибудь о "?". оператора и этой ошибки, потому что '?' Google игнорируется.

4b9b3361

Ответ 1

Попробуйте это вместо:

actions[actions.ContainsKey(pair.Key) ? pair.key : ""](pair.Value, pair.Key);

Это устранит вашу проблему.

Ответ 2

?: Условный оператор определяется как:

Условный оператор (?:) возвращает одно из двух значений в зависимости от значения булевого выражения

Ваши действия не возвращают значение, поэтому каково должно быть возвращаемое значение ?:?

Ответ 3

Если вам действительно нужно это делать, вы можете попробовать

actions[actions.ContainsKey(pair.Key) ? pair.Key : ""](pair.Value, pair.Key);

Просто чтобы уточнить, из : Operator (ссылка С#)

Условие должно оцениваться как true или false. Если условие истинно, first_expression оценивается и становится результатом. Если условие false, second_expression оценивается и становится результатом. Единственный из двух выражений.

это равнозначно

int input = Convert.ToInt32(Console.ReadLine());
string classify;

// if-else construction.
if (input < 0)
    classify = "negative";
else
    classify = "positive";

// ?: conditional operator.
classify = (input < 0) ? "negative" : "positive";

Ответ 4

Там нет ничего плохого в вашем разговоре. Выражение actions[pair.Key](pair.Value, pair.Key) действительно является вызовом. Это не выражение, которое жалуется компилятор. Компилятор ссылается на все выражение условного оператора, которое не является ни присваиванием, ни вызовом, ни приращением, ни декрементом, ни новым выражением объекта, и поэтому не может быть самостоятельным выражением.

Альтернативы включают следующее:

  • Присвоение результата выражения другой переменной, делая условное просто подвыражением более крупного оператора присваивания
  • Факторинг условного выражения в индексном выражении, поэтому общий оператор представляет собой один вызов, а не два отдельных вызова.
  • Используя два независимых оператора, чтобы решить, какой ключ использовать, а затем вызвать функцию:

    var key = actions.ContainsKey(pair.Key) ? pair.Key : "";
    actions[key](pair.Value, pair.Key);
    

    Он по-прежнему избегает дублирования кода, но делает его более легко читаемым, не пытаясь упаковать все в один сложный оператор.

Ответ 5

каждый оператор "?:" должен присваивать что-то, что означает, что

actions.ContainsKey(pair.Key) ? actions[pair.Key](pair.Value, pair.Key) : actions[""](pair.Value, pair.Key);

не является законным, поскольку он не присваивает ничего.

вы можете сделать:

object x = actions.ContainsKey(pair.Key) ? actions[pair.Key](pair.Value, pair.Key) : actions[""](pair.Value, pair.Key);

и это было бы законным, если actions[pair.Key](pair.Value, pair.Key) и actions[""](pair.Value, pair.Key); вернуть значение