5

I have a struct type in C#. I want to be able to convert null implicitly to this type. For instance, null could be represented by a special value of the struct type and the cast operator should return a struct with this value.

In C++, I could use an implicit cast operator overload of type std::nullptr_t. Is there a comparable type in C#?

I have had the idea to use a special NullType class which has no instances. This works but looks somehow ugly. Is there a better way?

Example:

class NullType
{
    private NullType(){} // ensures that no instance will ever be created
}

struct X
{
    private static readonly int nullValue = -1;
    private int val;

    public X(int val){ this.val= val; }

    public static implicit operator X(NullType t)
    { 
        return new X(nullValue);
    }
}

class MainClass
{
     public static void Main(string[] args)
     {
          X x = null; // Works now!
     }
}
gexicide
  • 38,535
  • 21
  • 92
  • 152
  • Why are you trying to do this? You can already check `.HasValue` of a nullable class? Also raises the question about struct vs class and your use cases. – Belogix Jul 16 '15 at 13:03
  • Good question. Apparently, this only works for nullable types [because of some compiler magic specific to them](http://stackoverflow.com/q/29574048/87698). – Heinzi Jul 16 '15 at 13:06
  • @Belogix: For space reasons, I don't want to use `Nullable` as it will insert a `bool` member into my struct which might cost me up to 8 bytes due to alignment restrictions. I rather want to model null as a special constant (see my updated example). The cast from null is just a convenient and readable way to construct a struct with the special null value. – gexicide Jul 16 '15 at 13:14
  • why do you use struct and not a class? – silver Jul 16 '15 at 13:24
  • 1
    @silver: Since storing these things on the heap would be overkill in my application. – gexicide Jul 16 '15 at 13:25
  • Smart solution :) You could also consider a static property (`X x = X.Null;`), which is what some structs in the `System.Drawing` namespace have (ie. `Point.Empty`). – C.Evenhuis Jul 16 '15 at 13:34
  • Are you really that hard pushed that 8 bytes is going to cause concern? C# and C++ handle memory differently and it is not right to say that struct will live on the stack... It could well go on the heap! – Belogix Jul 16 '15 at 13:35
  • have a look on that post http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx beside that if you will use objects you can enforce a single null object instead of multiple null structs... – silver Jul 16 '15 at 13:39
  • @Belogix: I am quite sure, if I create an array of 1 billion of these structs, they will live inside the array, not somewhere else on the heap. If I would use a class, I would have a huge overhead. If I spent 8 bytes more for the null value, it would cost me 8 gigabytes of RAM, just for the convenience of using `Nullable`. So, yes, I am pushed that hard :). – gexicide Jul 16 '15 at 13:59

1 Answers1

1

No, conversion operators only allow conversion from types, not from a specific value of a type, aka null, so there is no null conversion operator.

The best fitting operator without introducing own types would be this:

public static implicit operator X(object t)

But obviously you don't want to use this. It isn't very safe to use (t can be any value, and the only way to handle non-null cases in an exception).

That said, I think the way you've created it now, using a class that can't be initialized is the best way to do this. In fact the only question is: why do you want to use null, instead of 'just' an default value instance on your struct (X.Null).

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
  • @ your question: `null` feels more concise to me than `X.Null`. If the meaning of the value is really "treat it exactly as you would treat a null value if it was a class", then `null` seems to be the best fit. In addition, I have refactored the code. `X` was a class before. Therefore, there are many places where `null` is already used, so allowing this will require less effort. – gexicide Jul 16 '15 at 13:56
  • Okay, but then use it in the true meaning (aka: compiler supported) by using `Nullable`, but you don't want that. So it is either this or that. Don't worry, you just have to go one through your code. It will take an hour or two, but then you are done. – Patrick Hofman Jul 16 '15 at 13:59
  • Sadly, even if I would want to use `Nullable`, it would also not allow the `= null` syntax (cf. http://stackoverflow.com/questions/29574048/why-c-sharp-null-can-implicit-convert-to-system-nullablet-but-can-not-a-self). I.e., there is no compiler support for `Nullable`. – gexicide Jul 16 '15 at 14:00
  • 1
    You can. That is about a custom implementation of `Nullable`. `= null` is allowed. It is compiler magic. – Patrick Hofman Jul 16 '15 at 14:02