I want to use the ternary operator to determine whether or not a variable should change.
The code looks as follows:
var c = "hello";
var appendWorld = false;
c = appendWorld ? string.Concat(c, " world") : c;
Since the value in case appendWorld is false, is the same as it was before, I was wondering if there's a more concise way of writing this code.
Please keep in mind that this is just a simplified example.
I want to be able to write something like this: c = appendWorld ? string.Concat(c, " world"); where c automatically stays the same if appendWorld is false.
Does something like this exist?
The simplest solution I think is to use an if condition
if(appendWorld)
c = string.Concat(c, " world");
Related
C# provides conditional operator (?:) that returns one of two values depending on the value of a Boolean expression. eg
condition ? first_expression : second_expression;
My question is can we use the same syntax to call a method when condition is true? and when condition is false then do nothing
public void Work(int? val)
{
var list = new List<int>();
//ofcourse line below doesn't work
//but is it possible to call method when condition is true and else do nothing
val.HasValue? list.Add(val.value) : else do nothing
}
the ?: has also been referred to as the ternary operator in the past. Ternary, for three. if this, then do this, else do this.
You have two expressions. If this, do this. This is exactly the point of an if statement. You are trying to fit your case into a construct that it isn't designed for. Don't do this.
Use the correct operation for the job:
if(val.HasValue)
{
list.Add(val.value)
}
The C# conditional operator is used to return a different value depending on the evaluation of a condition. It is not meant to be used to to be used the way you are trying to in your question. It should like be used this :
int test = i > 3 ? 0 : 1;
test will then equal 0 if i is less than (or equal to) 3, or test will equal 1 if 3 is greater than 3.
To do what you want you will have to use a regular if statement (which you can still write in one line by the way) :
if (val.HasValue) list.Add(val.value);
The conditional/ternary operator is supposed to return a value and that very specific value must be assigned back to somewhere.
So, in that case you can do that, yes. But, it would lead to bad design.
In a regular case, one would do this:
int x = (a > b) ? a : b;
Now, lets assume AddToList() is your desired method when the condition renders to true and DoRest() is the method you want to invoke if the condition turns out to false.
In the aforementioned case, you'd end up doing something like this:
int result = val.HasValue? AddToList(val.value) : DoRest();
Now you have to rely on result for finding out which one has been called (if you ever need that) and it's not very expressive and doesn't point to proper code design.
If you get a tad more adventurous you'd end up with :
var actionToInvoke = val.HasValue ? (Action)AddToList: (Action)DoRest;
actionToInvoke();
In any case, none of these lead to very readable code.
So, sticking with a simple if(val.HasValue) would be the simplest way to go here.
The way null conditional operator works is you have to return a value for the variable you are assigning it to. So if you would like a string value or something else other than void you can call the method with out any problem. But to call a void method you can use a delegate.
delegate void DelMethod();
void Method() { }
void MethodTwo() { }
private void MyMethod()
{
DelMethod x;
x = condition == true ? (DelMethod)Method : (DelMethod)MethodTwo;
}
In Lua there is a nice feature for quickly checking if the result of a statement is nil or not and using short circuited version of or to react to the situation; something such as:
text = GetTextFromUser() or "default text"
which translates as assign the return value of GetTextFromUser() to text and if GetTextFromUser() returned nil, then assign "default text" to text
which basically is nice trick to use short circuit evaluation of or operator for assignment.
I'm wondering if c# || operators also has such capabilities or not. If no, what is the shortest way to achieve the same behavior? ternary operator? if statement?
Maybe the null-coalescing operator? https://msdn.microsoft.com/en-ie/library/ms173224.aspx
string a;
string b = a ?? "default value";
So your example would become:
string text = GetTextFromUser() ?? "default text"
You can create a simple method to return default value if condition fails
string GetValueOrDefault(string value, Func<bool, string> condition,
string defaultValue = "") => condition(value) ? value: defaultValue;
Usage
var text = GetValueOrDefault(GetTextFromUser(), o => o != nil, "default text");
P.S.: TODO generic version.
Clipboard.SetText(txtBox1.Text);
How can I use a ternary operator here to set the text of the clipboard to txtbox1.Text if txtbox1.Text is not equal to string null, (nothing) ?
Thanks
You cannot. You are calling "SetText" either way. The correct way to achieve that would be to not call SetText if the text is not null.
Using Clipboard.SetText( a ? b : c); would give you nothing here if you dont want to set the text (only except hoping that SetText would ignore a null) unless you want some default. in that case something like:
clipboard.SetText(string.IsNullOrEmpty(txtBox1.Text) ? "default text" : txtBox1.Text);
You don't. Just a simple if statement will work though:
if (!string.IsNullOrEmpty(txtBox1.Text)) {
Clipboard.SetText(txtBox1.Text);
}
Why do you want to use the ternary operator? If you don't need to SetText, then don't.
if (!String.IsNullOrEmpty(txtbox1.Text))
Clipboard.SetText(txtbox1.Text);
I suppose you could do
Clipboard.SetText(String.IsNullOrEmpty(txtbox1.Text) ? (default here, or as is: Clipboard.GetText()) : txtbox1.Text);
I would suggest simple if, with ternary operator I can not imagine adequate solution.
if (!String.IsNullOrEmpty(txtbox1.Text))
{
Clipboard.SetText(txtbox1.Text);
}
Ternary mess: (do not use this in a real application!!!)
Action executeAction = String.IsNullOrEmpty(txtbox1.Text)
? () => {}
: () => { Clipboard.SetText(txtbox1.Text); };
executeAction.Invoke();
I'm not a c# programmer at all, but need to get certain calculations from a C# app. No I ran into something that I'm not sure if what the output is
I have the following line of code
pageSizeFactor = PrintingRequirements.FormSize == FormSize.A4 ? 1 : 2;
I just need to confirm if I am correct, the above means the following, pageSizeFactor = the Formsize, so if the Formsize is A4 pageSizeFactor will be 1 else it will be 2?
Yes; if PrintingRequirements.FormSize is FormSize.A4, pageSizeFactor will be 1. Otherwise, it will be 2.
That operator (?:) is known as the conditional operator. It is also sometimes known as the ternary operator. Its syntax goes like this:
a ? b : c
If a evaluates to true, the result will be b; otherwise, it will be c.
That is the conditional operator:
result = boolean-expression ? expression-if-true : expression-if-false
Essentially if - else inline.
A simple way to write the code you provided is:
if (PrintingRequirements.FormSize == FormSize.A4){
pageSizeFactor = 1;
} else {
pageSizeFactor = 2;
}
It seems the compiler is not going let this syntax fly.
void main()
{
foo(false?0:"");
}
void foo(int i) {return;}
void foo(string s) {return;}
The only other way I can see of fixing this is something as follows:
void bar(object o)
{
if (o is string){//do this}
else{//im an int, do this}
}
Anyone have any better ideas?
You cannot use a method with a void return type in a ternary expression in this way. End of story.
To understand why this is, remember what the ternary operator actually does -- it evaluates to the following:
(condition ? [true value] : [false value])
What this implies is that the following code:
int x = a ? b : c;
Must be rewritable to:
int x;
if (a)
{
x = b;
}
else
{
x = c;
}
The two above are logically identical.
So how would this work with a method with void as its return type?
// Does this make sense?
int x = condition ? foo(s) : foo(i);
// Or this?
if (condition)
{
x = foo(s);
}
else
{
x = foo(i);
}
Clearly, the above is not legal.
That said, others' suggestions would otherwise be valid if only your foo overloads returned a value.
In other words, if your signatures looked like this:
object foo(string s);
object foo(int i);
Then you could do this (you're throwing away the return value, but at least it'll compile):
object o = condition ? foo(0) : foo("");
Anyway, the ol' if/else is your best bet, in this case.
The method call of foo is determined at compile time, so it cannot call a different method (or overload) based on the result of evaluating the condition. Instead, try something like this:
condition ? foo(0) : foo("")
This way, the compiler will succeed in performing overload resolution and will resolve the first call to foo(int) and the second call to foo(string).
EDIT: As noted by other, you cannot use the ?: operator as a statement, nor can you use methods which return void in it. If your actual methods return compatible types, you could do something like:
int result = condition ? foo(0) : foo("");
If not, you must use an if:
if (condition)
foo(0);
else
foo("");
You're example doesn't make a whole lot of sense (the second example doesn't relate to the first).
I think the first example would be fine as:
void main()
{
foo("");
}
Since 0 will never be passed anyway (false is always false) and you can't use the inline conditional operator without an assignment somewhere (which your example is lacking).
As for the second way, that is probably how I would prefer to see it:
void bar(object o)
{
if(o is string) foo(o as string);
else foo((int)o);
}
I wouldn't pass in an object as a parameter. The int will be boxed, which is a little less efficient. Let the compiler figure out which method to call.
If you wrote:
foo(0);
foo("");
The appropriate method would be called. You could also write:
if (condition) {
foo(0);
} else {
foo("");
}
Depending on what you're trying to do (your example is lacking in a little detail).
If you use Inline if expressions in C#, both parts before and after the ":" have to be of the same type. What you are intending would never work.
Even if you like to do something like this:
DateTime? theTime = true ? DateTime.Now : null;
The compiler is not satisfied. In this case you will have to use:
DateTime? theTime = true ? DateTime.Now : default(DateTime?);
The conditional operator needs the true and false part to be of the same type. Which is why it's not compiling.
var x = condition ? 0 : "";
What type should the compiler choose for x? If you really want it to choose object make a cast or you could force it to choose dynamic in which case method overload would still work but you loose type safety. Both are however strong smells.
Having to test the runtime type is usually a design error but with the limited code (that will always have the same result) it's hard to help with a different approach that would require testing on runtime types
This:
foo(false?0:"")
Could be this:
false ? foo(0) : foo("")
Both results of the conditional operator must of the same type (or be implicitly convertible). So foo(false ? 0 : "") won't work because it is trying to return an Int32 and a String. Here's more information on the conditional operator.
The fix I would do is change that line to false ? foo(0) : foo("").
EDIT: Derp, can't use a conditional operator just in the open like that. They can only be used for assignments. You'll have to use a if/else block. Not in one line, but it'll do in a pinch.