Using null-conditional bool? in if statement [duplicate] - c#

This question already has answers here:
Converting Nullable<bool> to bool
(6 answers)
Compiler Error for Nullable Bool
(5 answers)
cannot implicitly convert type 'bool?' to 'bool'. An explicit conversion exists (are you missing a cast?)
(9 answers)
Closed 5 years ago.
Why this code works:
if (list?.Any() == true)
but this code doesn't:
if (list?.Any())
saying Error CS0266 Cannot implicitly convert type 'bool?' to 'bool'
So why is it not a language feature making such an implicit conversion in the if statement?

An if statement will evaluate a Boolean expression.
bool someBoolean = true;
if (someBoolean)
{
// Do stuff.
}
Because if statements evaluate Boolean expressions, what you are attempting to do is an implicit conversion from Nullable<bool>. to bool.
bool someBoolean;
IEnumerable<int> someList = null;
// Cannot implicity convert type 'bool?' to 'bool'.
someBoolean = someList?.Any();
Nullable<T> does provide a GetValueOrDefault method that could be used to avoid the true or false comparison. But I would argue that your original code is cleaner.
if ((list?.Any()).GetValueOrDefault())
An alternative that could appeal to you is creating your own extension method.
public static bool AnyOrDefault<T>(this IEnumerable<T> source, bool defaultValue)
{
if (source == null)
return defaultValue;
return source.Any();
}
Usage
if (list.AnyOrDefault(false))

Related

Cannot assign 0 to a short variable in c# from a ternary [duplicate]

This question already has answers here:
No implicit int -> short conversion in ternary statement
(3 answers)
Closed 3 years ago.
I am trying to assign 0 to a short variable from a condition and it throws compile time error that
Cannot implicitly convert type 'int' to 'short'. An explicit
conversion exists (are you missing a cast?)
Refer below screenshot. The salesLineInput.Discount is a short and SalesLineEntity.Discount is a Nullable<double>:
This is some other code I tried (not the same as in the screenshot):
if(SalesLineEntity.Discount.HasValue)
salesLineInput.Discount = (short)(SalesLineEntity.Discount * 100);
else
salesLineInput.Discount = 0;
Why does the if work, but the ternary doesn't?
Cast the whole statement to short
salesLineItem.Discount = (short)(condition ? somecalc : 0);
or
salesLineItem.Discount = condition ? somecalc : (short)0;

Ternary expression cannot choose between two method groups [duplicate]

This question already has answers here:
Conditional operator and Comparison Delegate
(2 answers)
Conditional statement, generic delegate unnecessary cast
(4 answers)
Why doesn't the C# ternary operator work with delegates?
(2 answers)
How can I assign a Func<> conditionally between lambdas using the conditional ternary operator?
(4 answers)
Closed 4 years ago.
I have a choice between two statically defined converters, and I want to use a ternary expression to make the choice:
Func<Input, Output> converter = useConverter1
? MyConverter.Converter1
: MyConverter.Converter2;
The compiler will not accept this expression. It fails with a message saying "There is no implicit conversion between 'method group' and 'method group'".
The structure of MyConverteris
public static class MyConverter
{
public static Output Converter1(Input input)
{
....
}
public static Output Converter1(Input input)
{
....
}
}
Can I work around this without an if-else statement?

Why does this conditional statement not work and does an if-statement that seems to do the same thing work? [duplicate]

This question already has answers here:
Conditional operator assignment with Nullable<value> types?
(6 answers)
Nullable types and the ternary operator: why is `? 10 : null` forbidden? [duplicate]
(9 answers)
Closed 8 years ago.
I have this property:
int? firstClientID;
Why does this
firstClientID = dataRow.IsFirstClientIDNull()
? null
: (int.TryParse(dataRow.FirstClientID, out tempInt)
? tempInt
: 0);
not compile because
type of conditional statement cannot be determined since there is no
implicit conversion between null and int
and does
if (dataRow.IsFirstClientIDNull())
firstClientID = null;
else if (int.TryParse(dataRow.FirstClientID, out tempInt))
firstClientID = tempInt;
else
firstClientID = 0;
work? They seem to do the same thing.
From MSDN
Either the type of first_expression and second_expression must be the same, or an implicit conversion must exist from one type to the other.
i.e. You will need to ensure both legs of the conditional operator return the same type (i.e. cast through Nullable<int>).
firstClientID = dataRow.IsFirstClientIDNull()
? (int?)null
: (int.TryParse(dataRow.FirstClientID, out tempInt)
? tempInt
: 0);
(The conditional operator is not really the same as an if / then else branch, as the conditional operator must return data of the same type, whereas if can do anything in each leg of the branches, with no constraints on type compatability)

implicit conversion from generic interface type [duplicate]

This question already has an answer here:
implicit operator using interfaces
(1 answer)
Closed 9 years ago.
I have the following implicit conversion operator:
public static implicit operator InputArgument<T>(T value)
{
return new InputArgument<T>(value);
}
The following is code in an ASP.NET MVC controller:
This works:
InputArgument<string> input = "Something";
This works:
InputArgument<Controller> input = this;
This works:
InputArgument<IPrincipal> input = new InputArgument<IPrincipal>(User);
But this doesn't work:
InputArgument<IPrincipal> input = User;
The last example gives the error:
> Cannot implicitly convert type
> 'System.Security.Principal.IPrincipal' to
> 'Engine.InputArgument<System.Security.Principal.IPrincipal>'. An
> explicit conversion exists (are you missing a cast?)
What could be the reason that this implicit conversion does not work for IPrincipal?
User-defined conversions are specified as not working on interfaces. If they did work on interfaces like this then you could end up in a situation where Bar<IFoo> is converted to IFoo via a representation-changing user-defined conversion when the object actually implements IFoo, which would be surprising.

C# conditional operator ?: has problems with nullable int [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Conditional operator assignment with Nullable<value> types?
Why does the conditional operator “?:” not work here when my function is returning a nullable integer “int?”? “return null” works but with “?:” I have to cast “null” to “(int?)” first.
public int? IsLongName(string name) {
int length = name.Length;
// this works without problems
if (name.Length > 10) {
return null;
} else {
return name.Length;
}
// this reports:
// Type of conditional expression cannot be determined because
// there is no implicit conversion between '<null>' and 'int'
return name.Length > 10 ? null : name.Length;
}
Try changing your last line to this:
return name.Length > 10 ? null : (int?)name.Length;
The compiler can't understand what's the return type of the ?: operator. It has conflicting values - null and int. By casting the int to nullable, the compiler can understand the return type is nullable int, and null would be accepted as well.
Both a null value and an int value can be implicitly converted to an int? data type, but a literal of null on its own isn't known by the compiler to be anything other than an object if you don't tell it. There is no common data type that both object and int can be implicitly converted to, which is what the compiler is complaining about.
As Yorye says, you can cast the int to int? to let the compiler do the conversion; or, you can cast the null to int?, which then allows the compiled to use the implicit conversion from int to int?.
Both conditions of the ?: operator must be implicitly compatible. int can never be null, so there is a compile-time error (likewise, null can never be int). You have to cast, there's no way around it using the ternary.
I don't think you would have the same problem with an if statement, because the compiler would only check that the method returns a compatible value to the return type from any given path, not that the return value from any given exit point is implicitly compatible with another block's return value.
The ?: operator only considers the types of its two possible return values. It is not aware of the type of the variable that will receive its result (indeed, in more complex expressions, no explicit variable may exist).
If one of those return values is null, it has no type information - it can only check the other return value's type, and check whether a conversion exists.
In your case, we have null and a return value of type int. There is no conversion available. There would be a conversion to int?, but that is neither of the possible return types that ?: is considering.

Categories

Resources