I came across an interesting facet of the C# language this morning I have not experienced yet; consider the below code snippet:
public class Example
{
public int getInt()
{
int? myInt = 2;
return myInt; // <-- compiler error.
}
public object getObject()
{
object? obj = new { };
return obj; // <-- OK, no error.
}
}
The compiler returns an error on the commented line above:Error CS0266: Cannot implicitly convert type 'int?' to 'int'. An explicit conversion exists (are you missing a cast?) (CS0266)
What I find interesting is that the object example works just fine without complaining. I am assuming this is something to do with primitives vs. objects but I am unable to find any resources. I am aware the return type is not matching the object type, I just thought it was curious that it works with objects and not a primitive. If anyone could share some links/provide an explanation as to why this is, it would be greatly appreciated.
CodePudding user response:
int?
is syntactic sugar for Nullable<int>
, a generic type that is distinct from just plain int
. Thus, you can't return a Nullable<int>
in a method specified to return int
.
object
, like other reference types, is nullable by itself and doesn't need to be wrapped in Nullable<T>
, and thus can match the return type of getObject()
and be returned without error.
CodePudding user response:
When you call this getInt()
you are asking for an int
, not for an int?
. In this way, you can do this:
public int getInt()
{
int? myInt = 2;
if (myInt.HasValue)
{
return myInt.Value; // You must return .Value (int value)
}
else
{
/* You can dou something here, like change to default value and then return 'myInt.Value', p.e.*/
}
}
Anyway, you can use .HasValue
to know if a nullable attribute is null or not, and return the non-null value with .Value
.
In the other way, when you ask for getObject()
, you expect an object, wich can be any kind of type. This is why you have no errors on there.
CodePudding user response:
Similar to Chris' answer except the nullable object part.
The ?
is just syntax sugar for the Nullable<T>
generic type. This type implicitly inherits the type object
. Because Nullable<T>
inherits object
, the nullable object can be returned as type object
.
The Nullable<T>
does not inherit int
and therefore cannot be returned with a return type of int
.
Here's whats actually going on
public class Example
{
public int getInt()
{
Nullable<int> myInt = 2;
return myInt; // <-- compiler error.
}
public object getObject()
{
Nullable<object> obj = new { };
return obj; // <-- OK, no error.
}
}