0

I've two code snippets here, the first one produce an error, but the second work. Why?

public static Vector3? GetRayPlaneIntersectionPoint(Ray ray, Plane plane)
{
    float? distance = ray.Intersects(plane);
    return distance.HasValue ? ray.Position + ray.Direction * distance.Value : null;
}

Give: Type of conditional expression cannot be determined because there is no implicit conversion between '' and 'Microsoft.Xna.Framework.Vector3'

But the following snippet without ternary operator work just fine.

public static Vector3? GetRayPlaneIntersectionPoint(Ray ray, Plane plane)
{
    float? distance = ray.Intersects(plane);

    if (distance.HasValue)
        return ray.Position + ray.Direction * distance.Value;
    else
        return null;
}
  • possible duplicate of [Conditional operator assignment with Nullable types?](http://stackoverflow.com/questions/75746/conditional-operator-assignment-with-nullablevalue-types) – Eric Lippert Apr 29 '14 at 22:26
  • This question has been asked literally hundreds of times on this site. The C# language requires that the expression be evaluated from *inside* to *outside*. The fact that there is a conversion to a nullable type *outside* the expression does not influence how the *inside* of the expression is analyzed; rather, it is the opposite. Once the type of the inside of the expression is determined, it is compared to the type on the outside to see if it is compatible. – Eric Lippert Apr 29 '14 at 22:28
  • Guess there is a big misunderstanding that the conditional expressions should work the same, and the ternary operator is more of syntax sugar. – user3251046 Apr 29 '14 at 22:43
  • You make a valid point. The fact that hundreds or, more likely, thousands of people have been confused by this indicates that the design of the operator might be flawed. Or, another way to think about it: the rule is sensible, but the error message could be a lot more clear. It could say *"the consequence and alternative of the conditional operator must have a consistent type; the assignment suggests that the desired type is "Vector3?". Consider casting the consequence and/or alternative to the desired type."* – Eric Lippert Apr 29 '14 at 22:54

1 Answers1

1

Your first argument is of type Vector3 (NOT Vector3?). Since null is not a valid value for a Vector3, you get the error.

Change the line to:

float? distance = ray.Intersects(plane);
return distance.HasValue ? (Vector3?)(ray.Position + ray.Direction * distance.Value): null;

You need to explicitly cast the left hand side of the ternary to Vector3? for it to work. The second code snippet works because Vector3 can implicitly cast to Vector3?. In a ternary, this cast doesn't happen, so you have to do it explicitly.

BradleyDotNET
  • 60,462
  • 10
  • 96
  • 117