views:

195

answers:

5

If a value type is declared nullable, how should I take precautions for this? I.e. if in the constructor I have:

public Point3 ( Point3 source )
{
    this.X = source.X;
    this.Y = source.Y;
    this.Z = source.Z;
}

would it fail, if source was null?

+10  A: 

I don't see the possibility of Point3 being null if it's a value type. Don't you miss a question mark? And if you really mean Point3?, then you should access it like:

public Point3 ( Point3? source )
{
    this.X = source.Value.X;
    this.Y = source.Value.Y;
    this.Z = source.Value.Z;
}

and in this case, the Value property will throw an exception if it's null.

Mehrdad Afshari
Sorry I didn't know the type has to be written as nullable. I thought any value type can be declared like that.
Joan Venge
No, value types can't be null. Nullable types was a feature added to .NET 2.0 to fill this gap for value types. You have to explicitly use a nullable variable to be able to set it as null.
Mehrdad Afshari
Thanks. So I have to have a constructor like you have above to give the users the ability to declare Point3 as nullable, right? Can I also both include nullable constructors and regular ones for value types?
Joan Venge
No, it's not related to the value type. ANY value type can be declared as nullable by adding a question mark. In fact, the nullable type is really Nullable<T> and not T.
Mehrdad Afshari
Thanks. I have to read about them I think. I thought it's done if the developer gives nullable support as well as non-nullable support.
Joan Venge
Depends on the meaning of support. For declaring and using them, absolutely not. But it's up to the developer to add auxiliary methods that work on nullable version (get a nullable parameter, for example). In that case, just like any type, it should be explicitly declared as such.
Mehrdad Afshari
+2  A: 

Yes, that would fail if source was null.

You'll have to decide what the correct behavior should be if source is null. You might just throw an exception.

public Point3 ( Point3? source )
{
    if (source == null) 
    {
        throw new ArgumentNullException("source");
    }

    this.X = source.Value.X;
    this.Y = source.Value.Y;
    this.Z = source.Value.Z;
}

Or, if you don't want to accept null values for source, just keep the method as you have it in your example. That method doesn't accept a Nullable<Point3>, so you don't have to worry about it being null in that case.

bdukes
Nullable<T> doesn't have properties X, Y, Z... You should either use a cast or the Value property...
Mehrdad Afshari
Fixed, thanks .
bdukes
+3  A: 

The caller of this method will not be able to pass in a nullable point, since the method takes a regular point, not a Nullable one. Therefore, you don't need to worry about Point being null in your constructor code.

BFree
+1  A: 

If source was a Point3? it wouldn't be a Point3. So as far as I know, it would fail compile time. To send in a Point3? you would have to use .Value, which would throw an exception I believe if it was null.

Svish
+1  A: 
    public Point3(Point3? source) { 
       this.X = source.GetValueOrDefault().X; 
        this.Y = source.GetValueOrDefault().Y;
        this.Z = source.GetValueOrDefault().Z; 
    }