Nullable struct in c#

Started by
17 comments, last by Doggolainen 13 years, 5 months ago
Quote:Original post by Nik02
My previous comment was based on the assumption that the people here knew the implications of deferencing in general; thus, I omitted the explanation of cases in which the overhead does matter. Whether or not it is an issue depends exactly on the application.


Dereferencing is mostly a technical detail. I was more referring to recent design debate.

Reasoning typically goes that a coordinate might represent an object which is not part of current world or scene. Or that algorithm might need to return "no matches found". And one day, your coordinate, a pair of x/y float values becomes AsynchronousCachingLockStepSimulationManager.


A coordinate is typically just that, x/y pair. It doesn't need methods, doesn't have invariants, it's just a piece of data.

Concepts like nullable in algorithms dealing with them aren't needed. While they may add syntactic sugar in case of (x,y)/0, they don't really add anything - the result of such operation is not null - it is a coordinate. And if sticking with OO, then something like a Normal is not related to Vector2D, though inheritance is a good fit - Normal is a specialization of Vector2D. But in practice that is bordering on overdesign for little to no gain. It's also something where OOD falls flat on the face and an area which is hugely unaddressed by popular languages.

And regardless of how such result is returned - only the caller can answer the question of what to do with invalid values and must anticipate them. null doesn't provide any of that, it's mostly a cop out as evidenced by NullObject concept, which is different from nullable.


Perhaps the only confusing thing here is thinking that coordinate is different from a number. It's exactly the same, and 2+3 = null does not make sense either.

Situations where result is invalid must be addressed a priori, not as magic behavior hidden by operations.

Just because something can be done using language syntax doesn't mean it should be.
Advertisement
Quote:Original post by Nik02
As adt7 said, you can wrap a value type to a Nullable templated class in order to inject nullable traits to structs. This has a bit of overhead because the underlying values of nullable struct instances are effectively forced out of the stack. The "?" syntax is a shortcut to System.Nullable<T>.

Quote:Original post by ddboarm
Inclined to disagree...unless you can produce an actual resource that supports your claim. When a value type is made nullable, a reference type is created on the heap to reference the struct on the stack. Overhead? Really? Quite negligible I'm sure.

Quote:Original post by Nik02
The dereferencing itself is the source of the overhead. It is negligible in most practical cases, though.

None of this is correct. System.Nullable is a generic value type, not a reference type, and certainly not a "templated class" either. Nullable value types are still value types, and therefore are not references, not copied onto the heap, still exist on the stack, and do not require dereferencing to access.

You guys are arguing over the performance implications of a supposition that isn't even true to begin with.
Mike Popoloski | Journal | SlimDX
Quote:Original post by Antheus
Situations where result is invalid must be addressed a priori, not as magic behavior hidden by operations.


I think you're over thinking things. You shouldn't think of returning a nullable vector as some new type with a magic value, but rather just syntactic coating over a (bool, vector) tuple. Such a function returns two distinct values:

1. Was there a result.
2. If so, what was it.

And since the Nullable type doesn't provide implicit conversions to its wrapped data, I don't really see where any confusion would come in regarding what's going on. It's just a nice bit of syntactic sugar being able to write Vector?.
Quote:Original post by Mike.Popoloski
...


I stand corrected, sorry for the confusion. I was thinking of way older stuff than the implementation of nullables in .net 2.0 and later.

Niko Suni

Thanks for all your comments, especially to the #1 for the code snappet.

I'm sorry for not posting a situation where I want the posibility to return null. I have a funciton which returns a Vector2D (see it as a coordinate) where two rotated-rectangles intersects. In case there is no intersection I want to be able to return null.

The reason why I dont wan't to make a class out of it is because I want to use it simply as raw data. If I give an entity a coordinate I dont want it to be a reference to that coordinate, which would make it possible for several entities to have the same Vector2D referece. At the moment I solve this problem with a .Clone() function.

Feel free to dissagree I'm more than happy to learn something!

//Doggolainen
Quote:Original post by Doggolainen

I'm sorry for not posting a situation where I want the posibility to return null. I have a funciton which returns a Vector2D (see it as a coordinate) where two rotated-rectangles intersects. In case there is no intersection I want to be able to return null.


A rectangle/rectangle intersection can result in:
- empty set
- one to eight points
- one to four line segments

Depending on what else needs to be done, order might be either useful or important. Colinearity of edges might not sound important, but it covers many potentially degenerate cases.

But two rectangles will rarely intersect in single point.
Quote:Original post by Shinkage
Quote:Original post by Antheus
Situations where result is invalid must be addressed a priori, not as magic behavior hidden by operations.


I think you're over thinking things. You shouldn't think of returning a nullable vector as some new type with a magic value, but rather just syntactic coating over a (bool, vector) tuple. Such a function returns two distinct values:

1. Was there a result.
2. If so, what was it.

And since the Nullable type doesn't provide implicit conversions to its wrapped data, I don't really see where any confusion would come in regarding what's going on. It's just a nice bit of syntactic sugar being able to write Vector?.


When doing something like this, I prefer using out parameters or better yet, the new functional classes added in .NET 4.0, more specifically the Tuple class. It makes your intent much, much clearer with just the method signature alone.
The common pattern for this type of operation is a "Try___" function:

bool TryFindIntersection(inputargumentshere, out/ref Vector2D v);
Quote:Original post by Antheus
Quote:Original post by Doggolainen

I'm sorry for not posting a situation where I want the posibility to return null. I have a funciton which returns a Vector2D (see it as a coordinate) where two rotated-rectangles intersects. In case there is no intersection I want to be able to return null.


A rectangle/rectangle intersection can result in:
- empty set
- one to eight points
- one to four line segments

Depending on what else needs to be done, order might be either useful or important. Colinearity of edges might not sound important, but it covers many potentially degenerate cases.

But two rectangles will rarely intersect in single point.


I must first solove the case where two lines intersects, then I use the same code but for each side (4*4) of two rectangles.

@Nypren I will use outparameters for it. But just to make things clear: I use "out" for structs and "ref" for references, right?

[Edited by - Doggolainen on November 28, 2010 6:02:43 AM]

This topic is closed to new replies.

Advertisement