EduChapow Ответов: 3

Как Я Могу Использовать Тернарный Оператор Без Возврата Значения?


Здравствуйте люди,

Я хочу использовать такой тернарный оператор, но он не работает.

var itemToRemove = myCollection.Any(p => p != null).FirstOrDefault();
itemToRemove != null ?? myCollection.Remove(itemToRemove); //this don't compile!


Это возможно?

MCY

почему бы не использовать if?

BillWoodruff

@MCY на самом деле, вы можете достичь того, что OP явно пытается сделать здесь без 'if: смотрите мое решение ниже (примечание: в то время, когда я писал свой ответ, Решение OriginalGriff здесь не было видно).

johannesnestler

где находится тернарный оператор (в .NET есть только один, и я не вижу его в вашем примере)? Вы имеете в виду нуль-коалесцирующий оператор? Таким образом, вы не можете использовать оператор "вот так", потому что вы использовали неправильный синтаксис, и из приведенного примера кажется, что у вас также есть больше проблемы "как я должен это сделать". Так чего же вы хотите добиться в итоге?
Просто чтобы подвести итог что не так:
Any не возвращает коллекцию (возможно, не используйте синтаксический сахар, такой как var, если вы не знаете, как его использовать - если бы вы написали там "bool", ошибка могла бы быть очевидна для вас)
Таким образом bool не может быть null
Вы не назначаете что-то такое, чтобы операторы "? :" и "??" не работали (MSDN? просто нажмите F1 в VS на операторе...)
У вас есть ошибки компиляции - читайте их?

EduChapow

спасибо всем

3 Ответов

Рейтинг:
5

BillWoodruff

Ваш код не использует тернарный оператор: вы используете оператор"??", который вычисляет аргумент (переменную), и если значение не равно нулю, возвращает вычисленное значение; если значение равно нулю, то возвращается значение после"??". Пример:

string s1 = null;

string t1 = s1 ?? "whoop de doo"; // t1 now contains "whoop de doo"

string s2 = "hoop la";

string t2 = s2 ?? "yabba dabba doo" // t2 now contains "hoop la"
Вы можете использовать тернарный оператор, называемый Microsoft "условным оператором", который должен всегда возвращать значение:
string t3 = (s1 != null) ? t2 : "shake, rattle, and roll";
// t3 contains "shake, rattle, and roll"
С обоими ?? и тернарные операторы вы ограничены одним утверждением в каждом "сегменте", и вы надо что-то вернуть.

Ясно, что ваша цель здесь состоит в том, чтобы удалить элемент из коллекции. Имейте в виду, что оператор .NET Collections Remove<T> возвращает логическое значение, указывающее на успех или неудачу удаления; вы можете использовать это возвращаемое значение или игнорировать его. Если вам нужно отслеживать, было ли удаление успешным, попробуйте сделать это:
bool itemIsRemoved = myCollection.Remove(myCollection.FirstOrDefault(p => p != null));
Вот вам и вызов:
List<string> lStr = new List<string> {null, string.Empty, "0", "1", "41", "2", "3", "4", "5" };

var itmIsRemoved1 = lStr.Remove(lStr.FirstOrDefault(str => str != null));

var itmIsRemoved2 = lStr.Remove(lStr.FirstOrDefault(str => str == "4"));

var itmIsRemoved3 = lStr.Remove(lStr.FirstOrDefault(str => str == string.Empty));

var itmIsRemoved4 = lStr.Remove(lStr.FirstOrDefault(str => str == null));
Как вы думаете, какое значение имеет 'itmIsRemoved и значения в списке строк после выполнения каждой строки приведенного выше кода ?


Рейтинг:
25

OriginalGriff

Здесь есть пара проблем:
1) Any возвращает bool, не коллекция, так что вы не можете использовать FirstOrDefault на нем.
2) оператор null-coalescing работает не так. Прочтите описание MSDN: ?- Оператор[^]

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


EduChapow

OriginalGriff, спасибо за помощь 4U!
Это просто пример, я пишу очень быстро. мой настоящий вопрос таков!

я могу сделать что-то вроде этого:
itemToRemove != null ?? моя коллекция.Удалить(itemToRemove);

считайте, что itemToRemove в порядке

OriginalGriff

Нет, остановитесь и подумайте: что же это такое ?? оператор *do*?
Во - первых, это не утверждение ... ? всегда возвращает значение с той или иной стороны, и этот результат никуда не денется.
Во - вторых, левая и правая стороны должны быть одного типа- это прекрасно в вашем примере.
В-третьих, даже если вы действительно присвоите это значение, ошибка компиляции исчезнет:
bool b = itemToRemove != null ?? моя коллекция.Удалить(itemToRemove);
Remove никогда не будет вызван, потому что оператор != всегда возвращает bool, который является типом значения и, следовательно, не может содержать нулевое значение, поэтому право никогда не будет действовать.

Что ты пытаешься сделать?

EduChapow

спасибо, парень, ты ответил на мой вопрос.

- Во-первых, это не заявление ... ? всегда возвращает значение с той или иной стороны, и этот результат никуда не денется."

Итак, теперь я обычно использую if/else.

я просто хочу решить эту проблему в одной строке... ^^


OriginalGriff

Всегда пожалуйста!
Но в таком случае, я подозреваю, что вы что-то неправильно поняли! :смеяться:
Есть два оператора, которые используют '?': Нулевой коэлексивный оператор:
a = b ?? c;
где 'A' получает значение 'Б', если 'б' имеет значение null, в этом случае будет "с".

И тернарный оператор, который является краткой формой для оператора if...else... :
Если (а)
b = c;
еще
b = d;
Может стать:
Б = а ? С : D;
Итак, если " а "истинно, то" в "становится " С", иначе " В "становится " д".
Но...и всегда есть одно "но"... "С" и " Д " должны быть одного типа. Вы не можете вернуть null ни с одной стороны, и вы не можете вернуть два экземпляра класса, которые оба являются производным типом, даже если они происходят непосредственно от одного и того же базового типа.

[править]опечатка - один '?' вместо двойной '??' :МЗ: - OriginalGriff[/правка]

Рейтинг:
12

CHill60

Далее к решению OriginalGriff,

Тернарный оператор тоже так не работает
http://www.dotnetperls.com/ternary[^] - ключ к разгадке находится в названии "оператор"

Следуйте советам MCY и используйте if

if( itemToRemove != null)
    myCollection.Remove(itemToRemove);