web-dev-qa-db-fra.com

? opérateur sans autre partie

-Je utiliser C #? opérateur quand j'ai des instructions if qui affectent une ligne et tout va bien. Mais disons que j'ai ce code (en utilisant des instructions if classiques):

if(someStatement)
{
    someBool = true;  //someBools value is unknown
}
else
{
    //Do nothing
}

Cela peut être réalisé sur une seule ligne en faisant:

someBool = (someStatement) ? true : someBool;

Mais pourquoi ne puis-je pas faire quelque chose comme ça:

someBool = (someStatement) ? true : ;
//or possibly
someBool = (someStatement) ? true;

Est-ce possible d'une manière ou d'une autre? Si c'est le cas, y a-t-il des avantages à utiliser une méthode par rapport à l'autre? Et sinon, pourquoi ne devriez-vous pas pouvoir le faire?

22
Johan Hjalmarsson

Tu peux faire:

someBool = (someStatement) ? true : someBool;

Je ne pense pas que cela vous apporte beaucoup de clarté sur:

if (someStatement)
{
    someBool = true;
}

Mais cela semble vraiment être une question de goût. Je ne dirais pas non plus que c'est clairement mauvais, mais le premier est rare, donc je l'éviterais probablement.


Vous demandez pourquoi vous ne pouvez pas utiliser l'opérateur comme ceci:

someBool = (someStatement) ? true : ;

Ce serait un très gros changement de langue! Gardez à l'esprit qu'une affectation ressemble à ceci:

<location> = <expression>;

L'expression est évaluée pour donner une certaine valeur, et cette valeur est stockée dans l'emplacement. (Selon que l'emplacement est une variable, une propriété, un champ ou une expression d'indexation, l'opération de "stockage" peut être très différente.)

Ici, vous proposez que la valeur de l'expression à droite, en plus de ses valeurs normales, puisse être une valeur "sans changement", qui a le comportement spécial que lorsque vous l'utilisez dans une instruction d'affectation, elle ne provoque aucun stockage opération à se produire. C'est différent de toute autre valeur normale et potentiellement surprenant. Mais qu'est-ce que cela signifierait si vous l'utilisiez dans d'autres endroits?

// Does this call DoSomething when cond is false?
// If so, what value is passed to it?
someObject.DoSomething(cond?x:);

// What happens here if cond is false? Does it cancel
// the entire assignment?
int x = 77 + (cond?2:) * 3 - 4;

// If cond is false, are methods F1 and F2 called or not called?
int x = F1() + (cond?2:) + F2();

// What does this do? Does it skip the return if cond is false?
return (cond?2:);

Je pense que vous auriez beaucoup de mal à trouver un comportement sensible, intuitif et cohérent pour l'opérateur dans toutes ces circonstances, et je ne pense pas que cela serait utile ailleurs que dans une simple affectation. Cela ne correspond tout simplement pas au reste de la langue - y compris cela rendrait la langue plus difficile à apprendre, à lire, à comprendre, à mettre en œuvre et à expliquer. Ce n'est pas la peine pour un tout petit peu de concision.

21
Weeble

Fondamentalement, vous essayez d'utiliser l'opérateur conditionnel pour quelque chose pour lequel il n'est pas conçu.

Ce n'est pas censé facultativement prendre des mesures ... il est censé évaluer une expression ou une autre, et ce doit être le résultat de l'expression.

Si vous ne souhaitez effectuer une action que lorsqu'une condition est remplie, utilisez une instruction if - c'est précisément pour cela qu'elle est là.

Dans votre exemple, vous pourriez utiliser:

// Renamed someStatement to someCondition for clarity
someBool |= someCondition;

ou

someBool = someCondition ? true : someBool;

... en d'autres termes "utilisez la valeur existante à moins que someCondition ne soit vrai ... mais personnellement, je pense que la déclaration d'origine if est plus claire.

17
Jon Skeet

Quelques informations: nous utilisons beaucoup de constructions comme celle-ci:

sql = "SELECT x FROM table WHERE Y " + (condition ? " AND Column = 1" : "");

Nous utilisons également des constructions comme celle-ci dans les vues Razor

<div class='someclass @(condition ? "anotherclass" : "")'></div>

Le : "" est assez ennuyeux donc nous avons construit une méthode d'extension

public static T Then<T>(this bool value, T result)
{
    return value ? result : default(T);
}

Usage:

<div class='someclass @condition.Then("anotherclass")'></div>

tiré de ici

2
Alex