1

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.

3 Answers 3

5

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.

1
  • 2
    and if get getInt() return type was object. Then Nullable<int> would also match the return type.
    – Tom
    Commented May 5, 2022 at 15:33
1

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.
    }
}
0

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.

Not the answer you're looking for? Browse other questions tagged or ask your own question.