Is "long?" really a struct?

Viewed 181

By definition Nullable<> is a struct but when I call some generic function, it behaves like it's an object.

class GenController
{
    public void Get<T>(T id) where T : struct
    {
        Console.Write("is struct");
    }

    public void Get(object obj)
    {
        Console.Write("is object");
    }
}

long param1 = 1234;
new GenController().Get(param1);
// output is "is struct" as expected

long? param2 = 1234;
new GenController().Get(param2);
// output is "is object"
// obj seen at debug time as "object {long}"
// expected "is struct"

So the parameter is seen as an object instead of a struct.

Any idea of what's happening, am I misunderstanding the meaning of struct?

Is there a way to dispach Nullable<T> or T and object as different kind of parameters?

2 Answers

Nullable<T> is definitely a struct.

Your question is more about the where T : struct generic type constraint, than it is about Nullable<T>.

From the docs:

where T : struct: The type argument must be a non-nullable value type.

long? is a nullable value type, and so isn't permitted by the where T : struct constraint.

To answer the question:

  • Nullable<T> is a struct
  • The struct constraint only allows not nullable structs.

With that said, you can specify that the parameter is nullable, like this:

public void Get<T>(T? id)
    where T: struct
{
    Console.Write("is nullable struct");
}

That would be one more overload to capture nullable structs.

Related