Cast to Nullable in ternary operator C# creates new variable? - c#

Assume that we have exression:
int? someValue = SomeCondition ? 1 : (int?)null;
so when SomeCondition is false,
(int?)null
evaluates and will be new instance of int? created at this time for assign to someValue?

When SomeCondition is false, the value of the ternary-operator expression will be null.
The (int?) before the null is just casting it (not creating a new object).
The cast is required since the compiler enforces that both possible return values of the expression be of the same type (or convertible to a common type). So in this case, the compiler sees that int (the type of the 1) and int? (the casted type of the null) are convertible to (int?). Without the cast, the compiler has no way of reconciling null and int since value types cannot be null, and null has no natural type of its own.
You could also apply the (int?) cast to the 1 to achieve the same effect.

Related

?? and ternary operations with Bool? and Guid? types

I am trying to check the state of an object, if it is null then I need to return null, otherwise, I need to return a Guid or a Bool.
Portrait_Enabled = _SiteImagesModel_ImagesViewModel == null ? null : _SiteImagesModel_ImagesViewModel.Enabled,
Portrait_PrimaryImage = _SiteImagesModel_ImagesViewModel.PrimaryImage ?? null,
Portrait_RecordID = _SiteImagesModel_ImagesViewModel.RecordID ?? null,
Portrait_RelatedImage = _SiteImagesModel_ImagesViewModel.RelatedImage ?? null,
I have tried both the ?? and the ? : and I get a compiler error stating:
Type of conditional expression cannot be determined because there is no implicit conversion between <null> and bool
Operator ?? cannot be applied to operands of type bool and <null>
Operator ?? cannot be applied to operands of type Guid and <null>
Both the Guid and Bool values are Nullable.
The MS Docs explanation about null-coalescing operator (note emphasized part):
A nullable type can represent a value from the type’s domain, or the
value can be undefined (in which case the value is null). You can use
the ?? operator’s syntactic expressiveness to return an appropriate
value (the right hand operand) when the left operand has a nullible
type whose value is null. If you try to assign a nullable value type
to a non-nullable value type without using the ?? operator, you will
generate a compile-time error. If you use a cast, and the nullable
value type is currently undefined, an InvalidOperationException
exception will be thrown.
Since the right-hand operand must return appropriate value of corresponding data type, it can't be set directly as null even the assigned variable has nullable data type (both operands must be have same data type).
Basically when you define a null-coalescing operator as this:
Portrait_PrimaryImage = _SiteImagesModel_ImagesViewModel.PrimaryImage ?? [DefaultValueIfNull];
It will translated as this:
Portrait_PrimaryImage = _SiteImagesModel_ImagesViewModel.PrimaryImage == null ? [DefaultValueIfNull] : _SiteImagesModel_ImagesViewModel.PrimaryImage;
Since both operands in ternary operator & null-coalescing operator must have same type, if you still want null value to be passed, you can cast the right-hand operand to proper type like this:
Portrait_PrimaryImage = _SiteImagesModel_ImagesViewModel.PrimaryImage ?? (bool?)null;
Portrait_RecordID = _SiteImagesModel_ImagesViewModel.RecordID ?? (Guid?)null;
Portrait_RelatedImage = _SiteImagesModel_ImagesViewModel.RelatedImage ?? (bool?)null;
Note that null is not at the same type as Nullable<bool>, you need to cast into bool? to get same data type.
As in your case, ternary operator usage just enough, no need to use null-coalescing operator when the second operand is null:
Portrait_Enabled = _SiteImagesModel_ImagesViewModel == null ? null : (bool?)_SiteImagesModel_ImagesViewModel.Enabled;
Portrait_RecordID = _SiteImagesModel_ImagesViewModel == null ? null : (Guid?)_SiteImagesModel_ImagesViewModel.RecordID;
Portrait_RelatedImage = _SiteImagesModel_ImagesViewModel == null ? null : (bool?)_SiteImagesModel_ImagesViewModel.RelatedImage;
References:
Type of conditional expression cannot be determined because there is no implicit conversion between 'int' and <null>
How to set null to a GUID property

What does mean "?" after variable in C#?

What does this condition mean?
if (!helper?.Settings.HasConfig ?? false)
P.S.
helper is variable of some class
Settings is some field
HasConfig is field too
Well, ?. is a null-conditional operator
https://msdn.microsoft.com/en-us/library/dn986595.aspx
x?.y
means return null if x is null and x.y otherwise
?? is a null-coalescing operator
https://msdn.microsoft.com/en-us/library/ms173224.aspx
x ?? y
means if x == null return y, otherwise x
Combining all the above
helper?.Settings.HasConfig ?? false
means: return false if
helper == null or
helper.Settings.HasConfig == null
otherwise return
helper.Settings.HasConfig
The code without ?? and ?. if can be rewritten into cumbersome
if (!(helper == null
? false
: (helper.Settings.HasConfig == null
? false
: helper.Settings.HasConfig)))
Check the C# operator list:
x?.y – null conditional member access. Returns null if the left hand operand is null.
x ?? y – returns x if it is non-null; otherwise, returns y.
So helper?.Settings will return null if helper is null otherwise it will return helper.Settings
if helper.Settings is not null and helper.Settings.HasConfig is not null then it will return the value of helper.Settings.HasConfig otherwise will return false.
N.B: if helper?.Settings is null then NULL reference exception will occur.
?. Operator is known as the safe navigation operator introduced in C# 6.
Null Conditional Operator Syntax
The null conditional operator (?.) is colloquially referred to as the "Elvis operator" because of its resemblance to a pair of dark eyes under a large quiff of hair. The null conditional is a form of a member access operator (the .). Here's a simplified explanation for the null conditional operator:
The expression A?.B evaluates to B if the left operand (A) is non-null; otherwise, it evaluates tonull.
Many more details fully define the behavior:
The type of the expression A?.B is the type of B, in cases where B is
a reference type. If B is a value type, the expression A?.B is the
nullable type that wraps the underlying value type represented by B.
The specification for the feature mandates that A be evaluated no
more than once.
The null conditional operator short-circuits, which means that you
can chain multiple ?.operators, knowing that the first null
encountered prevents the remaining (rightmost) components of the
expression from being evaluated.
Example:- Suppose we have a Student class
public class Student
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
Assume that s represents a student. Consider these two statements:
var name = s?.FirstName;
var age = s?.Age;
The variable name is a string. The value of name depends on the value of s. If s is null, name is null. If s is not null, name is the value of s.FirstName. Note that s.FirstName may be null even when s is not.
The variable age is an int? (which is another way of specifying a Nullable). As with name, the value of age depends on the value of s. If s is null, age is an int? with no value. If s is non-null, age is the wrapped value of s.Age.
That's the basics. The power of this feature comes from all the scenarios where this feature enables cleaner code.
It will check if "helper" is not NULL before acessing "Settings" property to avoid NullReferenceException. https://msdn.microsoft.com/en-us/library/dn986595.aspx
"Old" way was like this: if (helper != null && !helper.Settings......).

C# : Implicit conversion between '<null>' and 'bool'

I got a weird error message when I tried to convert an object to bool, here is my code:
public partial class ModifierAuteur : DevExpress.XtraEditors.XtraForm
{
public ModifierAuteur(object getKeyDecesCheckBox)
{
decesCheckBox.Checked = getKeyDecesCheckBox == null ? null : (bool)getKeyDecesCheckBox;
}
}
and this is the error message :
Type of conditional expression cannot be determined because there is
no implicit conversion between <null> and bool
Assuming that the assignment is possible, you need to convert to a nullable bool, like this:
decesCheckBox.Checked = getKeyDecesCheckBox == null ? null : (bool?)((bool)getKeyDecesCheckBox);
The inner cast to bool unboxes the value, and the outer cast to bool? makes it compatible with null of the conditional expression.
If the left-hand side of the assignment does not allow nulls, you need to decide on the value to set when getKeyDecesCheckBox is null. Usually, that's a false:
decesCheckBox.Checked = getKeyDecesCheckBox == null ? false : (bool)getKeyDecesCheckBox;
Assuming the Checked property is of type nullable bool, I would probably do the following:
decesCheckBox.Checked = (getKeyDecesCheckBox == null ? (bool?)null : (bool?)getKeyDecesCheckBox);
If it takes a bool (not-nullable) you can convert the null to false easily with:
decesCheckBox.Checked = (getKeyDecesCheckBox == null ? (bool?)null : (bool?)getKeyDecesCheckBox).GetValueOrDefault();
decesCheckBox.Checked is of type bool. As such you must feed it either false or true.
Your '? :' operator has two possible incompatible return types: if the object is null, then it returns the value null, which can be cast to any nullable type. If the object is not null, then its return type is bool.
I don't know what type 'Checked' is, but I suspect that its type is 'bool'.
The problem here is that you can't cast null to the 'bool' type, and so you have to decide what type you want it to be in the case the object is null. If you wanted it to be false, you could write the statement as:
decesCheckBox.Checked = (getKeyDecesCheckBox as bool) ?? false;
The ?? Operator assigns the value 'false' in the case where the object is null, or cannot be converted to a bool.

C# Handling Null Values

I have CustomerID declared as
int? CustomerID=null;
I am checking null values while reading DataReader
Id = reader["CustomerId"] is DBNull ? null :Convert.ToInt32(reader["CustomerID"]);
It is throwing
Type of conditional expression cannot be determined because there
is no implicit conversion between '<null>' and 'int'
What is the problem with the Conversion?
I think you need to do it this way:
if(! reader.IsDBNull(reader.GetOrdinal("CustomerId"))
{
Id = Convert.ToInt32(reader["CustomerID"]);
}
else
{
Id = NULL;
}
You need to use the .IsDBNull method on the reader to determine ahead of time if a column is NULL - if it is, don't even read the value from the reader.
Change your conditon to
reader["CustomerId"] == DBNull.Value
A ?: conditional expression cannot evaluate to two different types on the true and false condition. I think a cast (int?)null should work.
The problem (assuming that Id is declared properly) is that the conditional statement infers the result type from the true result. In your case, that type is null. It then will try to cast the second type to the same as the first...and there is no cast from int to null.
The solution is to cast the true expression to the desired type:
Id = reader["CustomerId"] == DBNull.Value ?
(int?) null :
Convert.ToInt32(reader["CustomerID"]);
Try this
Id = reader["CustomerId"] is DBNull ? (int?)null : Convert.ToInt32(reader["CustomerID"]);
the types of both parts of the ?: need to be explicit
What's happening is your code is incorrectly evaluating and trying to do the Convert function.
Its readding reader["CustomerId"] is DBNull which it isn't its really a DBNull.Value so then it attempts to do Convert.ToInt32("<null>") and crashes. You need to fix your if statement, and add a (int ?) cast.
It should be:
Id = reader["CustomerId"] is DBNull.Value ? (int?) null :Convert.ToInt32(reader["CustomerID"]);

Difference between is and as keyword

Please tell what is the difference between is and as keyword in C#
is
The is operator checks if an object can be cast to a specific type.
Example:
if (someObject is StringBuilder) ...
as
The as operator attempts to cast an object to a specific type, and returns null if it fails.
Example:
StringBuilder b = someObject as StringBuilder;
if (b != null) ...
Also related:
Casting
The cast operator attempts to cast an object to a specific type, and throws an exeption if it fails.
Example:
StringBuilder b = (StringBuilder)someObject.
The Difference between IS and As is that..
IS - Is Operator is used to Check the Compatibility of an Object with a given Type and it returns the result as a Boolean (True Or False).
AS - As Operator is used for Casting of Object to a given Type or a Class.
Ex.
Student s = obj as Student;
is equivalent to:
Student s = obj is Student ? (Student)obj : (Student)null;
Both is and as keywords are used for type casting in C#.
When you take a look at the IL code of usages of both the keywords, you will get the difference easily.
C# Code:
BaseClass baseclassInstance = new DerivedClass();
DerivedClass derivedclassInstance;
if (baseclassInstance is DerivedClass)
{
derivedclassInstance = (DerivedClass)baseclassInstance;
// do something on derivedclassInstance
}
derivedclassInstance = baseclassInstance as DerivedClass;
if (derivedclassInstance != null)
{
// do something on derivedclassInstance
}
IL code (for above C# code is in the attached image):
The IL code for is keyword usage contains IL instructions both isinsta and castclass.
But the IL code for as keyword usage has only isinsta.
In the above mentioned usage, two typecast will happen where is keyword is used and only one typecast where as keyword is used.
Note: If you are using is keyword to check some condition and do not have any interest in the typecast result, then there will be only one typecast, i.e.
if (baseclassInstance is DerivedClass)
{
// do something based on the condition check.
}
is and as keywords will be used based on the necessity.
The is keyword checks whether the value on its left side is an instance of the type on the right side. For example:
if(obj is string)
{
...
}
Note that in this case you'll have to use an extra explicit cast to get obj as string.
The as keyword is used to cast nullable types. If the specified value is not an instance of the specified type, null is returned. For example:
string str = obj as string;
if(str != null)
{
...
}
is OPERATOR
The is operator in C# is used to check the object type and it returns a bool value: true if the object is the same type and false if not.
or also The “is” operator is used to check whether the run-time type of an object is compatible with a given type or not.
For null objects, it returns false
e.g
if(obj is AnimalObject)
{
//Then Work
}
as OPERATOR
The as operator does the same job of is operator but the difference is instead of bool, it returns the object if they are compatible to that type, else it returns null.In otherwords, The ‘as‘ operator is used to perform conversions between compatible types.
e.g
Type obj = Object as Type;
Advantages of as over is
In case of is operator, to type cast, we need to do two steps:
Check the Type using is
If it’s true then Type cast
Actually this affects the performance since each and every time the CLR will go through the inheritance hierarchy, checking each base type against the specified type.
To avoid this, use as, it will do it in one step. Only for checking the type should we use the is operator.
I would say: read MSDN online, but here it is:
The is operator checks whether an object is compatible with a given type, and the result of the evaluation is a Boolean: true or false.
The as operator will never throw an exception.
Is operator , a cast, returns true if it succeeds. It returns false if the cast fails. With it, you cannot capture the converted variable. This operator is most useful when checking types in if-statements and expressions.The is-cast is only ideal if the resulting variable will not be needed for further use
As is a cast. With it, we gain performance and avoid exceptions when a cast is invalid. Null is returned when the cast is impossible. For reference types, the as-cast is recommended. It is both fast and safe.We can test the resulting variable against null and then use it. This eliminates extra casts
is operator checks whether the object is compatible with the given
type the result based upon true or false.
as is used to cast one type to another type and on conversion
failure results null except then raising exception.
well see link for better understanding with examples https://blogs.msdn.microsoft.com/prakasht/2013/04/23/difference-between-direct-casting-is-and-as-operator-in-c/
The As operator is similar to a cast, but returns null instead of an exception if it fails.
And the Is operator is used to check if one object is compatible with a certain type. It's usually used in If statements.
is: The is operator is used to check whether the run-time type of an object is compatible with a given type
as: The as operator is used to perform conversions between compatible types.
object s = "this is a test";
string str=string.Empty;
if( s is string)
str = s as string;
MyClass myObject = (MyClass) obj;
vs
MyClass myObject = obj as MyClass;
The second will return null if obj isn't a MyClass, rather than throw a class cast exception.
is will only return true or false
Both IS and AS are used for Safe Type Casting
IS Keyword-->
checks whether the type of an given object is compatible with the new object type. It Never Throws an exception. This is a Boolean type..returns either true or false
`student stud = new student(){}
if(stud is student){} // It returns true // let say boys as derived class
if(stud is boys){}// It returns false since stud is not boys type
//this returns true when,
student stud = new boys() // this return true for both if conditions.`
AS Keyword:
checks whether the type of an given object is compatible with the new object type. It returns non-null if given object is compatible with new one, else null.. This throws an exception.
`student stud = new student(){}
// let say boys as derived class
boys boy = stud as boys;//this returns null since we cant convert stud type from base class to derived class
student stud = new boys()
boys boy = stud as boys;// this returns not null since the obj is pointing to derived class`
Both operator are used for safe type casting.
AS Operator :
The AS operator also checks whether the type of a given object is compatible with the new object type. This keyword will check whether the type of a given object is compatible with the new object type. If it's not compatible with the new one then it will return NULL.
IS Operator:
This Operator checks whether the type of an object is compatible with the new object. If it's compatible it returns true otherwise false.

Categories