2017-12-21 153 views
6

Mam następujący kod C# -W C operatora # potrójnego daje błąd: tylko zadanie, wezwanie, przyrost, ubytek i nowych wyrażeń przedmiot mogą być wykorzystywane jako oświadczenie

using System; 

class Program 
{ 
    static void Main() 
    { 
     int number = 1; 
     int isNumber10; 
     (number==10)?(isNumber10=1):(isNumber10=0); 
     Console.WriteLine(isNumber10); 
    } 
} 

Na kompilacji wyskakuje mi błąd -

error CS0201: Only assignment, call, increment, decrement, and new object expressions can be used as a statement

w C jestem przyzwyczajony do następującego kodu -

#include <stdio.h> 
int main(){ 
    int isNumber10; 
    int number = 1; 
    (number==10)?(isNumber10=1):(isNumber10=0); 
    printf("%d\n",isNumber10); 
    return 0; 
} 

Ten kod działa idealnie.

Teraz oba programy są dokładnie takie same. Dlaczego więc działa w C, ale nie w C#?

+3

Ponieważ C# nie jest C, nawet w większości przypadków nie jest blisko. – NetMage

+2

Złe sprawiają, że post wygląda ładnie zamiast tego –

Odpowiedz

10

Operator trójskładnikowy jest wyrażeniem, którego nie można użyć jako instrukcji. W przeciwieństwie do tego przypisanie jest wyrażeniem, które może być promowane do instrukcji. (Stąd komunikat o błędzie odnoszący się do „przypisanie” wyrażeń)

Co chcesz to:

isNumber10 = number == 10 ? 1 : 0; 

Tutaj są za pomocą operatora ?: jako wyraz, który rozpoznaje jednego z dwóch wartości (1 lub 0) i jest następnie przypisana do zmiennej isNumber10.

mieć trochę zabawy z tym, jeśli tworzone tą metodą:

public void M<T>(T value) 
{ 
} 

I nazwał to lubią:

M((number==10)?(isNumber10=1):(isNumber10=0)); 

To będzie działać prawidłowo. Problem polega na tym, że gramatyka C# nie pozwala większości nagich wyrażeń żyć w kontekście, w którym wartość wyrażenia nie jest zużywana. (Pamiętaj, że definiowanie różnicy między wyrażeniem a instrukcją jest takie, że wyrażenie tworzy wyrażenie, ale instrukcja nie) Niektóre wyrażenia są dozwolone poza tym przewodnikiem - na przykład wywołując metodę, która zwraca wartość. Te stały się w języku technicznym "expression statement". I użytecznie, jedynymi kandydatami na wyrażenia, które mogą być promowane w oświadczeniach, są dokładnie określone przez komunikat o błędzie w tytule twojego pytania.

Większość z nas myśli o zadaniach jako o oświadczeniach, ale jest bardziej fundamentalnie wyrażeniem. (zwraca wartość przypisaną podczas równoczesnego wykonywania przypisania). Właśnie dlatego to puste połączenie z M faktycznie spełni twoje oczekiwania. (Nie jest on bardzo czytelny)

Z Twojego komentarza, dodam ten komentarz jako część mojej odpowiedzi:

The only error of yours is the simple fact that the C# grammar doesn't allow it. It certainly could, but well, it does not. I'm reminded about how the when operator in SQL is an expression (meaning you can say set i = when x is null then 'A' else 'B') whereas in C# such a usage would be invalid (since the switch statement is not an expression -- it cannot return a value)

+0

Ale w moim kodzie sprawdzam warunek - (liczba == 10)? jeśli true, instrukcja jest (isNumber10 = 1), jeśli false jest instrukcja (isNumber10 = 0), gdzie jest błędna w tym podejściu? – puregeek

+0

@puregeek Może pójść [przeczytaj dokumentację] (https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/conditional-operator), prawdopodobnie byłby lepszym miejscem do rozpoczęcia. – DavidG

+0

@DavidG Czytam, ale proszę mi wyjaśnić, gdzie jest błąd gramatyczny w moim podejściu? Najpierw sprawdzam warunek, jeśli to prawda, coś robię, jeśli fałsz robię coś, – puregeek

1

spróbuj tego:

int number = 1; 
int isNumber10 = (number == 10) ? 10 : 0; 

Console.WriteLine(isNumber10); 
+0

Znam tę metodę, ale oba podejścia powinny być poprawne, dlaczego mój nie jest poprawny? – puregeek

+0

to dlatego, że wstawiasz znacznik zamykający tego 'int isNumber10;' Zamiast ';' musi to być '='; –

+0

Musi to wyglądać tak: 'int isNumber10 = (number == 10)? (isNumber10 = 1): (isNumber10 = 0); 'ale nie jest dobrym zwyczajem w programowaniu ponieważ alokuje przestrzeń. właściwą drogą jest 'int isNumber10 = number == 10? 10: 0; ' –

0

Problemem jest to, że C gramatyka i gramatyka C# są różne.

daję prosty przykład -

Jest człowiekiem John

W C następujące oświadczenie jest ważne -

(John has beard)?(Ask John to save):(ask John to not save); 

Tu John musi być określana dwa razy.

także następujące stwierdzenie jest ważny -

Ask John to = (John has beard)? (save):(not save); 

Tu John jest określany tylko raz.

ale w C# tylko następujące oświadczenie jest ważne -

Ask John to = (John has beard)? (save):(not save); 

takiego w danym kodzie -

Prawidłowe C składnia -

(number==10)?(isNumber10=1):(isNumber10=0); 

a także -

isNumber10 = (number==10)? 1:0; 

, ale w C# tylko następująca składnia jest poprawna -

isNumber10 = (number==10)? 1:0; 
Powiązane problemy