This is related to conventions used in C#.
I've got a method that has two parameters (X and Y coordinates). These coordinates represent the position at which a "tile" may reside. If a tile resides at these coordinates, the method returns its number. If no tile resides at these coordinates, I'm wondering how the method should behave.
I see three options:
Use exceptions. I may raise an exception every time Method finds no tile. However, as this situation is not rare, this option is the worst one.
Do it the old fashioned C++ way and return -1 if there is no tile.
Make the tile number a reference parameter and change the return type of method to boolean to show whether there is a tile or not. But this seems a bit complicated to me.
So, what should I do?
You can return null, and check for this on the calling code.
Of course you'd have to use a nullable type:
int? i = YourMethodHere(x, y);
Return -1.
This is not just a C++ convention, it's also common in the .NET Framework - e.g. methods like String.IndexOf or properties like SelectedIndex for controls that represent lists.
EDIT
Just to elaborate, of the three options in your question (Exception, return -1, out parameter), returning -1 is the way to go. Exceptions are for exceptional situations, and the Microsoft coding guidelines recommends avoiding out parameters where possible.
In my view returning -1 (provided it's always going to be an invalid value), returning a nullable int, or returning a Tile object are all acceptable solutions, and you should choose whichever is most consistent with the rest of your app. I can't imagine any developer would have the slightest difficulty with any of the following:
int tileNumber = GetTile(x,y);
if (tileNumber != -1)
{
... use tileNumber ...
}
int? result = GetTile(x,y);
if (result.HasValue)
{
int tileNumber = result.Value;
... use tileNumber ...
}
Tile tile = GetTile(x,y);
if (tile != null)
{
... use tile ...
}
I'm not sure I understand Peter Ruderman's comment about using an int being "much more efficient than returning a nullable type". I'd have thought any difference would be negligible.
Exceptions are for exceptional cases, so using exceptions on a known and expected error situation is "bad". You also are more likely, now, to have try-catches everywhere to handle this error specifically because you expect this error situation to happen.
Making your return value a parameter is acceptable if your only error condition (say -1) is confusable with a real value. If you can have a negative tile number then this is a better way to go.
A nullable int is a possible alternative to a reference parameter but you are creating objects with this so if an "error" is routine they you may be making more work this way than a reference parameter. As Roman pointed out in a comment elsewhere you will have C# vs. VB issues with the nullable type being introduced too late for VB to provide nice syntactic sugar like C# has.
If your tiles can only be non-negative then returning -1 is an acceptable and traditional way to indicate an error. It would also be the least expensive in terms of performance and memory.
Something else to consider is self-documentation. Using -1 and an exception are convention: you'd have to write documentation to make sure the developer is aware of them. Using an int? return or a reference parameter would better self-describe itself and wouldn't require documentation for a developer to know how to handle the error situation. Of course :) you should always write the documentation, just like how you should floss your teeth daily.
Use a nullable return value.
int? GetTile(int x, int y) {
if (...)
return SomeValue;
else
return null;
}
This is the clearest solution.
If your method has access to the underlying tile objects, another possibility would be to return the tile object itself, or null if there is no such tile.
I would go with option 2. You're right, throwing an exception in such a common case may be bad for performance, and using an out parameter and returning a true or false is useful but screwy to read.
Also, think of the string.IndexOf() method. If nothing is found, it returns -1. I'd follow that example.
You could return -1, as that is a fairly common C# approach. However, it might be better to actually return the tile that was clicked, and in the event that no tile was clicked, return a reference to a singleton NullTile instance. The benefit of doing it this way is that you give a concrete meaning to each value returned, rather than it just being a number that has no intrinsic meaning beyond its numeric value. A type 'NullTile' is very specific as to its meaning, leaving little to doubt for other readers of your code.
The best options are to return a boolean as well or return null.
e.g.
bool TryGetTile(int x, int y, out int tile);
or,
int? GetTile(int x, int y);
There are several reasons to prefer the "TryGetValue" pattern. For one, it returns a boolean, so client code is incredibly straight forward, eg: if (TryGetValue(out someVal)) { /* some code */ }. Compare this to client code which requires hard-coded sentinel value comparisons (to -1, 0, null, catching a particular set of exceptions, etc.) "Magic numbers" crop up quickly with those designs and factoring out the tight-coupling becomes a chore.
When sentinel values, null, or exceptions are expected it's absolutely vital that you check the documentation on which mechanism is used. If documentation doesn't exist or isn't accessible, a common scenario, then you have to infer based on other evidence, if you make the wrong choice you are simply setting yourself up for a null-reference exception or other bad defects. Whereas, the TryGetValue() pattern is pretty close to self-documenting by it's name and method signature alone.
I have my own opinion on the question that you asked, but it's stated above and I've voted accordingly.
As to the question that you didn't ask, or at least as an extension to all of the answers above: I would be sure to keep the solution to similar situations consistent across the app. In other words, whatever answer you settle on, keep it the same within the app.
If the method is part of a low level library, then your standard .NET design probably dictates that you throw exceptions from your method.
This is how the .NET framework generally works. Your higher level callers should catch your exceptions.
However since you seem to be doing this from a UI thread, which has performance implications since you are responding to UI events - I do what Jay Riggs already suggested, return null, and make sure your callers check for a null return value.
I'd break it into two methods. Have something like CheckTileExists(x,y) and GetTile(x,y). The former returns a boolean that indicates whether or not there is a tile at the given coordinates. The second method is essentially the one you're talking about in your original post, except it should throw an exception when given invalid coordinates (since that indicates the caller didn't first call CheckTileExists(), so it is legitimately an exceptional situation. For the sake of speed, you'd probably want these two methods to share a cache, so that in the event they're called one after the other, the overhead on the GetTile() function would be negligible. I don't know if you already have a suitable object to put these methods on or if perhaps you should make them two methods on a new class. IMHO, the performance penalty of this approach is negligible and the increase in code clarity far outweighs it.
Is it possible you have created (or could create) a Tile object that is referenced at the coordinates? If so, you can return a reference to that tile or null if there is no tile at the given coordinates:
public Tile GetTile(int x, int y) {
if (!TileExists(x, y))
return null;
// ... tile lookup here...
}
Related
So I didn't find any elegant solution for this, either googling or throughout stackoverflow. I guess that I have a very specific situation in my hands, anyway here it goes:
I have a object structure, which I don't have control of, because I receive this structure from an external WS. This is quite a huge object, with various levels of fields and properties, and this fields and properties can or can't be null, in any level. You can think of this object as an anemic model, it doesn't have behaviour, just state.
For the purpose of this question, I'll give you a simplified sample that simulates my situation:
Class A
PropB1
PropC11
PropLeaf111
PropC12
PropLeaf112
PropB2
PropC21
PropLeaf211
PropC22
PropLeaf221
So, throughout my code I have to access a number of these properties, in different levels, to do some math in order to calculate what I need. Basically for each type of calculation that I have to do, I have to test each level of the properties that I need, to check if it's not null, in which case I would return (decimal) 0, or any other default value depending on the business logic.
Sample of a math that I have to do with it:
var value = 0;
if (objClassA.PropB1 != null && objClassA.PropB1.PropC11 != null) {
var leaf = objClassA.PropB1.PropC11.PropLeaf111;
value = leaf.HasValue ? leaf.Value : value;
}
Just to be very, the leaf properties of this structure would always be primitives, or nullable primitives in which case I give the proper treatment. This is "the logic" that I have to do for each property that I need, and sometimes I have to use quite some of them. Also the real structure is quite bigger, so the number of verifications that I would need to do, would also be bigger for each necessary property.
Now, I came up with some ideas, none of them I think is ideal:
Create methods to gather the properties, where it would abstract any necessary verification, or the logic to get default values. The drawback is that it would have, in my opinion, quite some duplicated code, since the verifications and the default values would be similar for some groups of fields.
Create a single generic method, where it receives a object, and a lamba function that access the required field. This method would try to execute the function and return it's result, and in case of an NullReferenceException, it would return a default value. The bright side of this one, is that it is realy generic, I just have to pass lambdas to access the properties, and the method would handle any problem. The drawback of it, is that I am using try -> catch to control logic, which is not the purpose of it, and the code might look confusing for other programmers that would eventually give maintenance to it.
Null Object Pattern, this would be the most elegant solution, I guess. It would have all the good points if it was a normal case. But the thing is the impact of providing Null Objects for this structure. Just to give a bit more of context, the software that I am working on, integrates with government's services, and the structure that I am working with, which is in the government's specifications, have some fields where null have some meaning which is different from a default value like "0". Also this specification changes from time to time, and the classes are generated again, and the post processing that I would have to do to create Null Objects, would also need maintenance, which seems a bit dangerous for me.
I hope that I made myself clear enough.
Thanks in advance.
Solution
This is a response as to how I solved my problem, based on the accepted answer.
I'm quite new to C#, and this kind of discution that was linked really helped me to come up with a elegant solution in many aspects. I still have the problem that depending where the code is executed, it uses .NET 2.0, but I also found a solution for this problem, where I can somewhat define extension methods: https://stackoverflow.com/a/707160/649790
And for the solution itself, I found this one the best:
http://www.codeproject.com/Articles/109026/Chained-null-checks-and-the-Maybe-monad
I can basically access the properties this way, and just do the math:
objClassA.With(o => o.PropB1).With(o => PropC11).Return(o => PropLeaf111, 0);
For each property that I need. It still isn't just:
objClassA.PropB1.PropC11.PropLeaf111
ofcourse, but it is far better that any solution that I found so far, since I was unfamiliar with Extension Methods, I really learned a lot.
Thanks again.
There is a strategy for dealing with this, involving the "Maybe" Monad.
Basically it works by providing a "fluent" interface where the chain of properties is interrupted by a null somewhere along the chain.
See here for an example: http://smellegantcode.wordpress.com/2008/12/11/the-maybe-monad-in-c/
And also here:
http://www.codeproject.com/Articles/109026/Chained-null-checks-and-the-Maybe-monad
http://mikehadlow.blogspot.co.uk/2011/01/monads-in-c-5-maybe.html
It's related to but not quite the same as what you seem to need; however, perhaps it can be adapted to your needs. The concepts are fairly fundamental.
Let’s say I have double length that can be either a real length or not ready yet since we got no length yet in the server and there is nothing to send to the client. We need to pass this length from the server to the client as part of a fixed data protocol. The client currently uses the length only once, but might use it more than that in the future.
Pass double length and bool isLengthValid, and in every place you use length, check if isLengthValid
-Clean design without mixing data types but user have to remember to check
Pass double? length, and in every place you use length, check if length==null
-Design is clear (since it’s a nullable) but if you look and the type. Also – there will be an exception if someone uses without checking (good and bad, depends how you look at it)
Make a class Length instead of double. The class will have a clear interface of GetLengthIfYouCheckedIt or something.
Very readable and hard to make mistakes but design is a little over done.
What is your solution?
I say option2:
What you want is precisely why nullables were introduced.
Instead of adding a method to check wether it's a valid number or not, you'd use the built-in Nullable<double>.HasValue, just as it was meant for it.
Making a class for Length makes it doubly closed: it's only for LENGTH and it holds a Double. Think of how many of such classes you'll have to make and maintain for TIME/DateTime, MONEY/Decimal etc. It will never end.
The option 1 is just your own rolled Nullable<T> rewrapped with another name.
In other words, enforce the DRY principle, and use Nullable<T> ;)
HTH,
Bab.
I'd pass a double?. That's essentially a double + a bool value indicating if it's valid so using the 1) option would just be reinventing nullable. I think that the 3) option is overkill.
My advise would be that use nullable like this public Double? Length;
You will get methods like Length.HasValue, and Length.Value this will make the code easy to read and quicker for you to use( i mean no need to write new class etc by quicker for you)
Why not just keep it as a length parameter but return -1?
If possible, I would suggest making the request async, so that you do not return anything to the client until the data is actually ready.
If that is not possible, go with the second option.
When writing an API or reusable object, is there any technical reason why all method calls that return 'void' shouldn't just return 'this' (*this in C++)?
For example, using the string class, we can do this kind of thing:
string input= ...;
string.Join(input.TrimStart().TrimEnd().Split("|"), "-");
but we can't do this:
string.Join(input.TrimStart().TrimEnd().Split("|").Reverse(), "-");
..because Array.Reverse() returns void.
There are many other examples where an API has lots of void-returning operations, so code ends up looking like:
api.Method1();
api.Method2();
api.Method3();
..but it would be perfectly possible to write:
api.Method1().Method2().Method3()
..if the API designer had allowed this.
Is there a technical reason for following this route? Or is it just a style thing, to indicate mutability/new object?
(x-ref Stylistic question concerning returning void)
EPILOGUE
I've accepted Luvieere's answer as I think this best represents the intention/design, but it seems there are popular API examples out there that deviate from this :
In C++ cout << setprecision(..) << number << setwidth(..) << othernumber; seems to alter the cout object in order to modify the next datum inserted.
In .NET, Stack.Pop() and Queue.Dequeue() both return an item but change the collection too.
Props to ChrisW and others for getting detailed on the actual performance costs.
Methods that return void state more clearly that they have side effects. The ones that return the modified result are supposed to have no side effects, including modifying the original input. Making a method return void implies that it changes its input or some other internal state of the API.
If you had Reverse() return a string, then it wouldn't be obvious to a user of the API whether it returned a new string or the same-one, reversed in-place.
string my_string = "hello";
string your_string = my_string.reverse(); // is my_string reversed or not?
That is why, for instance, in Python, list.sort() returns None; it distinguishes the in-place sort from sorted(my_list).
Is there a technical reason for following this route?
One of the C++ design guidelines is "don't pay for features you don't use"; returning this would have some (slight) performance penalty, for a feature which many people (I, for one) wouldn't be inclined to make use of.
The technical principal that many others have mentioned (that void emphasizes the fact the function has a side-effect) is known as Command-Query Separation.
While there are pros and cons to this principle, e.g., (subjectively) clearer intent vs. more concise API, the most important part is to be consistent.
I'd imagine one reason might be simplicity. Quite simply, an API should generally be as minimal as possible. It should be clear with every aspect of it, what it is for.
If I see a function that returns void, I know that the return type is not important. Whatever the function does, it doesn't return anything for me to work with.
If a function returns something non-void, I have to stop and wonder why. What is this object that might be returned? Why is it returned? Can I assume that this is always returned, or will it sometimes be null? Or an entirely different object? And so on.
In a third-party API, I'd prefer if that kind of questions just never arise.
If the function doesn't need to return anything, it shouldn't return anything.
If you intend your API to be called from F#, please do return void unless you're convinced that this particular method call is going to be chained with another nearly every time it's used.
If you don't care about making your API easy to use from F#, you can stop reading here.
F# is more strict than C# in certain areas - it wants you to be explicit about whether you're calling a method in order to get a value, or purely for its side-effects. As a result, calling a method for its side-effects when that method also returns a value becomes awkward, because the returned value has to be explicitly ignored in order to avoid compiler errors. This makes "fluent interfaces" somewhat awkward to use from F#, which has its own superior syntax for chaining a series of calls together.
For example, suppose we have a logging system with a Log method that returns this to allow for some sort of method chaining:
let add x y =
Logger.Log(String.Format("Adding {0} and {1}", x, y)) // #1
x + y // #2
In F#, because line #1 is a method call that returns a value, and we're not doing anything with that value, the add function is considered to take two values and return that Logger instance. However, line #2 not only also returns a value, it appears after what F# considers to be the "return" statement for the function, effectively making two "return" statements. This will cause a compiler error, and we need to explicitly ignore the return value of the Log method to avoid this error, so that our add method has only a single return statement.
let add x y =
Logger.Log(String.Format("Adding {0} and {1}", x, y)) |> ignore
x + y
As you might guess, making lots of "Fluent API" calls that are mainly about side-effects becomes a somewhat frustrating exercise in sprinkling lots of ignore statements all over the place.
You can, of course, have the best of both worlds and please both C# and F# developers by providing both a fluent API and an F# module for working with your code. But if you're not going to do that, and you intend your API for public consumption, please think twice before returning this from every single method.
Besides the design reasons, there is also a slight performance cost (both in speed and space) for returning this.
The example below may not be problematic as is, but it should be enough to illustrate a point. Imagine that there is a lot more work than trimming going on.
public string Thingy
{
set
{
// I guess we can throw a null reference exception here on null.
value = value.Trim(); // Well, imagine that there is so much processing to do
this.thingy = value; // That this.thingy = value.Trim() would not fit on one line
...
So, if the assignment has to take two lines, then I either have to abusereuse the parameter, or create a temporary variable. I am not a big fan of temporary variables. On the other hand, I am not a fan of convoluted code. I did not include an example where a function is involved, but I am sure you can imagine it. One concern I have is if a function accepted a string and the parameter was "abused", and then someone changed the signature to ref in both places - this ought to mess things up, but ... who would knowingly make such a change if it already worked without a ref? Seems like it is their responsibility in this case. If I mess with the value of value, am I doing something non-trivial under the hood? If you think that both approaches are acceptable, then which do you prefer and why?
Thanks.
Edit: Here is what I mean when I say I am not a fan of temp variables. I do not like code like this:
string userName = userBox.Text;
if (userName.Length < 5) {
MessageBox.Show("The user name " + userName + " that you entered is too short.");
....
Again, this may not be the best way to communicate a problem to the user, but it is just an illustration. The variable userName is unnecessary in my strong opinion in this case. I am not always against temporary variables, but when their use is very limited and they do not save that much typing, I strongly prefer not to use them.
First off, it's not a big deal.
But I would introduce a temp variable here. It costs nothing and is less prone to errors. Imagine someone has to maintain the code later. Better if value only has 1 meaning and purpose.
And don't call it temp, call it cleanedValue or something.
It is a good practice not to change the values of incoming parameters, even if you technically can. Don't touch the value.
I am not a big fan of temporary variables.
Well, programming is largely about creating temporary variables all over the place, reading and assigning values. You'd better start to love them. :)
One more remark regarding properties. Although you could technically put a lot of logic there, it is recommended to keep properties simple and try not to use any code that could throw exceptions. A need to call other functions may indicate that this property is better be made a method or that there is some initialization code needed somewhere. Just rethink what you're doing and whether it does really look like a property.
I need to derive an important value given 7 potential inputs. Uncle Bob urges me to avoid functions with that many parameters, so I've extracted the class. All parameters now being properties, I'm left with a calculation method with no arguments.
“That”, I think, “could be a property, but I'm not sure if that's idiomatic C#.”
Should I expose the final result as a property, or as a method with no arguments? Would the average C# programmer find properties confusing or offensive? What about the Alt.Net crowd?
decimal consumption = calculator.GetConsumption(); // obviously derived
decimal consumption = calculator.Consumption; // not so obvious
If the latter: should I declare interim results as [private] properties, also? Thanks to heavy method extraction, I have several interim results. Many of these shouldn't be part of the public API. Some of them could be interesting, though, and my expressions would look cleaner if I could access them as properties:
decimal interim2 = this.ImportantInterimValue * otherval;
Happy Experiment Dept.:
While debugging my code in VS2008, I noticed that I kept hovering my mouse over the method calls that compute interim results, expecting a hover-over with their return value. After turning all methods into properties, I found that exposing interim results as properties greatly assisted debugging. I'm well pleased with that, but have lingering concerns about readability.
The interim value declarations look messier. The expressions, however, are easier to read without the brackets. I no longer feel compelled to start the method name with a verb. To contrast:
// Clean method declaration; compulsive verby name; callers need
// parenthesis despite lack of any arguments.
decimal DetermineImportantInterimValue() {
return this.DetermineOtherInterimValue() * this.SomeProperty;
}
// Messier property declaration; clean name; clean access syntax
decimal ImportantInterimValue {
get {
return this.OtherInterimValue * this.SomeProperty;
}
}
I should perhaps explain that I've been coding in Python for a decade. I've been left with a tendency to spend extra time making my code easier to call than to write. I'm not sure the Python community would regard this property-oriented style as acceptably “Pythonic”, however:
def determineImportantInterimValue(self):
"The usual way of doing it."
return self.determineOtherInterimValue() * self.someAttribute
importantInterimValue = property(
lambda self => self.otherInterimValue * self.someAttribute,
doc = "I'm not sure if this is Pythonic...")
The important question here seems to be this:
Which one produces more legible, maintainable code for you in the long run?
In my personal opinion, isolating the individual calculations as properties has a couple of distinct advantages over a single monolothic method call:
You can see the calculations as they're performed in the debugger, regardless of the class method you're in. This is a boon to productivity while you're debugging the class.
If the calculations are discrete, the properties will execute very quickly, which means (in my opinion), they observe the rules for property design. It's absurd to think that a guideline for design should be treated as a straightjacket. Remember: There is no silver bullet.
If the calculations are marked private or internal, they do not add unnecessary complexity to consumers of the class.
If all of the properties are discrete enough, compiler inlining may resolve the performance issues for you.
Finally, if the final method that returns your final calculation is far and away easier to maintain and understand because you can read it, that is an utterly compelling argument in and of itself.
One of the best things you can do is think for yourself and dare to challenge the preconceived One Size Fits All notions of our peers and predecessors. There are exceptions to every rule. This case may very well be one of them.
Postscript:
I do not believe that we should abandon standard property design in the vast majority of cases. But there are cases where deviating from The Standard(TM) is called for, because it makes sense to do so.
Personally, I would prefer if you make your public API as a method instead of property. Properties are supposed to be as 'fast' as possible in C#. More details on this discussion: Properties vs Methods
Internally, GetConsumption can use any number of private properties to arrive at the result, choice is yours.
I usually go by what the method or property will do. If it is something that is going to take a little time, I'll use a method. If it's very quick or has a very small number of operations going on behind the scenes, I'll make it a property.
I use to use methods to denote any action on the object or which changes the state of an object. so, in this case I would name the function as CalculateConsumption() which computes the values from other properties.
You say you are deriving a value from seven inputs, you have implemented seven properties, one for each input, and you have a property getter for the result. Some things you might want to consider are:
What happens if the caller fails to set one or more of the seven "input" properties? Does the result still make sense? Will an exception be thrown (e.g. divide by zero)?
In some cases the API may be less discoverable. If I must call a method that takes seven parameters, I know that I must supply all seven parameters to get the result. And if some of the parameters are optional, different overloads of the method make it clear which ones.
In contrast, it may not be so clear that I have to set seven properties before accessing the "result" property, and could be easy to forget one.
When you have a method with several parameters, you can more easily have richer validation. For example, you could throw an ArgumentException if "parameter A and parameter B are both null".
If you use properties for your inputs, each property will be set independently, so you can't perform the validation when the inputs are being set - only when the result property is being dereferenced, which may be less intuitive.