?: ?? 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.