It depends whether arguments that are out of range may occur in a regular way or if such method calls are considered being abusive.
If such arguments are regular, then return null
(that's perfectly okay).
If such arguments are abusive, then throw an exception.
An exception should always catch an error and never be misused for a test.
If the purpose of the method is not only to return a sprite, but also to test whether a sprite is available for a set of parameters, then you could use the same pattern as with Dictionary<T>.TryGetValue
:
public bool TryGetSprite(int x, int y, out Sprite sprite)
{
...
}
Use it like this:
Sprite sprite;
if (obj.TryGetSprite(x, y, out sprite)) {
// Sprite available
} else {
// No sprite available
}
When the return type is a non-nullable type, this is a good option. Magic numbers like 0
, -1
or Int32.MinValue
are not obvious and are not always available (if the full range of values is required as a regular result). Even null
might be a regular result under certain circumstances; for instance, a dictionary is allowed to contain null
values. If you need this distinction between contains null and not found, the TryGet... approach is perfect.
The advantage over returning null
is that you don't need additional knowledge apart from the method's signature in order to know how it works. Otherwise you are not sure whether an exception will be thrown or whether null
or even an empty Sprite
will be returned without reading the documentation. The disadvantage of TryGetSomething
is that is looks somewhat cumbersome. However, starting with C#7.0 / Visual Studio 2017, you can declare the variable inline: obj.TryGetSprite(x, y, out var sprite)
or obj.TryGetSprite(x, y, out Sprite sprite)
.
GetSprite
method used? And what is it used for? \$\endgroup\$Point
a value type? You'd have to return aNullable<Point>
for a null return value to work.. \$\endgroup\$GetSprite
doesn't return a "Sprite", but we'd need more context to recommend better alternatives. \$\endgroup\$