?: ?? Operatory zamiast IF | ELSE


85
public string Source
{
    get
    {
        /*
        if ( Source == null ){
            return string . Empty;
        } else {
            return Source;
        }
        */
        return Source ?? string.Empty;
    }
    set
    {
        /*
        if ( Source == null ) {
            Source = string . Empty;
        } else {
            if ( Source == value ) {
                Source = Source;
            } else {
                Source = value;
            }
        }
        */
        Source == value ? Source : value ?? string.Empty;
        RaisePropertyChanged ( "Source" );
    }
}

Czy mogę używać ?: ??operatorów DOKŁADNIE jako Jeśli / Inaczej?


Moje pytanie:
Jak napisać to za pomocą?: ?? operatorów

[1]

if ( Source == null ){
    // Return Nothing
} else {
    return Source;
}

[2]

if ( Source == value ){
    // Do Nothing
} else {
    Source = value;
    RaisePropertyChanged ( "Source" );
} 

W skrócie : jak nic nie robić, nic nie zwracać i wykonywać wiele instrukcji z ?: ??operatorem?


1
Jednak nie będzie zachowywać się tak samo. Nie używając warunkowego rozgałęziania if / else, bezwarunkowo (i niepotrzebnie) ponownie przypisujesz zmienną za każdym razem, gdy uzyskujesz do niej dostęp. Może to bardzo szybko się zepsuć, zwłaszcza jeśli masz kod wielowątkowy. Po prostu tego nie rób.
— Jeff Mercado

1
Będziesz mieć wywołanie niekończące się / rekurencyjne, jeśli metoda dostępu get właściwości Source zwraca właściwość Source (jej akcesor get).
— John K

1
Twój pierwszy fragment kodu ma właściwość pobierającą, która wywołuje swój własny ustawiający , który z kolei rekurencyjnie wywołuje swój własny moduł pobierający . Straciłeś mnie tam, bo nie ma mowy, żeby coś takiego działało w terenie. Sprecyzuj swoje pytanie i wyjaśnij dokładnie, co chcesz osiągnąć.
— Frédéric Hamidi

Nic nie zwracać? To jest VB. Piszesz c # tutaj.
— Zadanie

@Task Chodzi mi o to, jak to zrobić, ta linia jest komentarzem do pytania
— Ahmed Ghoneim

Odpowiedzi:


198

W przypadku [1] nie możesz: te operatory mają zwracać wartość, a nie wykonywać operacji.

Ekspresja

a ? b : c

oblicza, że bjeśli ajest prawdą i oblicza, że cjeśli ajest fałszem.

Ekspresja

b ?? c

szacuje, że bif bnie jest null, i oblicza, że cif bjest null.

Jeśli piszesz

return a ? b : c;

lub

return b ?? c;

będą zawsze coś zwrócić.

W przypadku [2] możesz napisać funkcję, która zwraca właściwą wartość, która wykonuje Twoje „operacje wielokrotne”, ale jest to prawdopodobnie gorsze niż zwykłe używanie if/else.


41

Operator trójargumentowy ( ?:) nie jest przeznaczony do sterowania przepływem , jest przeznaczony tylko do przypisywania warunkowego . Jeśli chcesz kontrolować przepływ swojego programu, użyj struktury kontrolnej, takiej jak if/ else.


5
Dodam, że widziałem ludzi używających zagnieżdżonych wyrażeń trójskładnikowych zamiast if / else i tworzyło kod, który jest trudny do odczytania i debugowania. Złe mojo dookoła.
— ckramer

4
Czasami zagnieżdżone operatory trójskładnikowe tworzą bardziej czytelny kod, jeśli białe znaki są używane prawidłowo.
— trutheality

2
@truth: Tak, nie mam nic przeciwko zagnieżdżeniu jako takiego ?:. Ale mam duży problem z tym, że są używane do sterowania przepływem, a zwłaszcza zagnieżdżonym przepływem sterowania!
— Oliver Charlesworth

11

Odnosząc się do ?: Operator (odwołanie w C #)

Operator warunkowy (? :) zwraca jedną z dwóch wartości w zależności od wartości wyrażenia boolowskiego. Poniżej znajduje się składnia operatora warunkowego.

Odnosząc się do ?? Operator (odwołanie w C #) Operator (C # Reference)

?? Operator jest nazywany operatorem łączenia wartości null i służy do definiowania wartości domyślnej dla typów wartości dopuszczających wartość null, a także typów odwołań. Zwraca operand po lewej stronie, jeśli nie jest pusty; w przeciwnym razie zwraca prawy operand.

To znaczy:

[Część 1]

return source ?? String.Empty;

[Część 2] nie ma zastosowania ...


3
To różni się od robienia niczego. Zwraca pusty ciąg.
— prawdomówność

1
Jasne, ale nie o to prosił OP. To nie moja wina, że ​​OP zażądał „niczego nie zwracać” - cokolwiek to może oznaczać.
— trutheality

1
@trutheality: Nikt nie powiedział, że to twoja wina .. Jednak OP nie chciał nic zwrócić i to, co zapewniłem.
— Akram Shahda

3

„Nic nie rób” tak naprawdę nie działa?

if przez // Return Nic, co właściwie masz na myśli, return null to napisz

return Source;

jeśli masz na myśli, zignoruj ​​ścieżkę kodu, a następnie napisz

 if ( Source != null )
            {
                return Source;
            }
// source is null so continue on.

I na koniec

 if ( Source != value )
            { Source = value;
                RaisePropertyChanged ( "Source" );
            }

// nothing done.

3

Operator trójargumentowy ZWRACA jedną z dwóch wartości. Lub może wykonać jedną z dwóch instrukcji na podstawie swojego stanu, ale generalnie nie jest to dobry pomysł, ponieważ może prowadzić do niezamierzonych skutków ubocznych.

bar ? () : baz();

W tym przypadku () nic nie robi, podczas gdy baz coś robi. Ale tylko uczyniłeś kod mniej przejrzystym. Wybrałbym bardziej szczegółowy kod, który jest jaśniejszy i łatwiejszy w utrzymaniu.

Co więcej, nie ma to w ogóle sensu:

var foo = bar ? () : baz();

ponieważ () nie ma typu zwracanego (jest void), a baz ma typ zwracany, który jest nieznany w momencie wywołania w tym przykładzie. Jeśli się nie zgodzą, kompilator będzie głośno narzekał.


2

Jeśli martwisz się szczegółowością twojego kodu, napiszę to, zamiast próbować nadużywać wyrażeń.

if (Source == value) return;
Source = value;
RaisePropertyChanged("Source");

Nie nadużywam wyrażeń, po prostu myślę!
— Ahmed Ghoneim

1

?: jest operatorem trasy. (uwierz, że poprawnie to przeliterowałem) i jest prosty w użyciu. jak w predykacie boolowskim? iftrue: ifalse; Ale musisz mieć rvalue / lvalue jak w rvalue = predicate? iftrue: iffalse;

dawny int i = x < 7 ? x : 7;

jeśli x było mniejsze niż 7, zostałbym przypisany x, jeśli nie, byłbym 7.

możesz również użyć go w zamian, jak w return x < 7 ? x : 7;

ponownie, jak powyżej, miałoby to taki sam wpływ.

więc Source = Source == value ? Source : string.Empty;wierzę , że to jest to, co próbujesz osiągnąć.


6
Lubię to. Trasa operator : pomaga dostać z punktu A do punktu B ... lub od A do C ... w zależności od A.
— Rick Sladkeya

Tak, ma na myśli trójskładnik. Ale poprawna nazwa to „warunkowa”.
— Erick G. Hagstrom


0

Nie sądzę, żebyś mógł to być operatorem i przypuszcza, że ​​zwróci jeden lub drugi. To nie jest zamiana instrukcji if else, chociaż można jej użyć do tego w niektórych przypadkach.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.