|
Well, gosh ... if I only had a Baht (about 2.86 US cents) for every time I've written: if(whatever != null) ...
However, is it, perhaps, useful to distinguish two scenarios:
1. checking for null when there's no need to throw an error if the whatever is null, and, the code context makes it absolutely clear what's going on.
2. checking for null when you absolutely should throw an error on null
I recognize there are "purists" who would like to see you throw errors in all cases.
And, how about this: disclaimer: this is an experiment I did a while ago; I am not indirectly expressing the opinion that anyone should use something like this:
public static class ErrorExtensions
{
public static bool IsNonNull<T>(this T refobj, bool throwerror = false, string message = null)
where T : class
{
if (refobj == null)
{
string mess = string.Format("instance of {0} is null: {1}",typeof(T).Name, message);
if (throwerror)
{
throw new NullReferenceException(mess);
}
else
{
#if ErrorsToConsole
Console.WriteLine(mess);
#endif
}
return false;
}
return true;
}
}
«There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008
modified 27-Jul-16 4:13am.
|
|
|
|
|
IsNotNull?
Also, you should not be purposely throwing an error from an extension method, as part of some divine plan. Just check if it is null or not, that is all. Leave the implementation to the calling party - this helps with code reuse (I may not want to do a console.writeline ).
My 2 unsolicited cents on your post.
|
|
|
|
|
Christ! Can't you read?
He wants 2.86 cents.
Michael Martin
Australia
"I controlled my laughter and simple said "No,I am very busy,so I can't write any code for you". The moment they heard this all the smiling face turned into a sad looking face and one of them farted. So I had to leave the place as soon as possible."
- Mr.Prakash One Fine Saturday. 24/04/2004
|
|
|
|
|
Well, I am afraid someone took me off the "divine plan" update service some years ago.
Please note:
1. the code will throw an error in the Extension method only when the 'throwerror parameter is 'true, and, of course, the instance of the generic parameter T (constrained to Type 'Class) is null.
2. the code will only call Console.WriteLine when the compiler directive '#define ErrorsToConsole is included at the start of the file. One would expect this to be present only in the developer's code who is using the source.
Again, keep in mind this is only an experiment.
I gladly accept your 2 cents !
cheers, Bill
«There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008
|
|
|
|
|
I prefer this style of coding
try
{
someObj.SomeMethod();
}
catch (Exception)
{
Response.Redirect("http://www.codeproject.com/search.aspx?q=Object+reference+not+set+to+an+instance+of+an+object&sbo=qa");
}
|
|
|
|
|
Here we go . After so many years of coding, I've learned to cull back on the wordiness of the code. Still, I have a few wonder brothers who "read code so fluently" that things get opaque pretty quick. I try to stay away from the "//declare variables" nonsense and lean toward higher level explanations of code blocks.
One thing that will set me off is when people don't use version control. So, you'll get interspersed lines of code that are commented out with new lines of code that fix a problem. One leaves this in the source in case if you need to remember what you changed. FFS, use "show changes".
Charlie Gilley
<bold>Do not forget Jacques Hamel
"Where liberty dwells, there is my country." B. Franklin, 1783
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
|
|
|
|
|
There're times when the sort of commented old code crap can be useful. Like when you were given a source dump for an ancient MFC app that the customer wants an update to and find yourself going "WTF this pile of code looks like it was obsolete even when MFC was new. C with classes every once in a while is a revolting way to write C++." for weeks on end, finding that one file that never got cleaned up and is full of commented code to create X-Windows GUI components can be enlightening in an "OH. The original version of this dinosaur was apparently a C/Slowlaris application before being ported to the then new and shiny NT4 and MFC in the late 90s." sort of way.
Did you ever see history portrayed as an old man with a wise brow and pulseless heart, waging all things in the balance of reason?
Is not rather the genius of history like an eternal, imploring maiden, full of fire, with a burning heart and flaming soul, humanly warm and humanly beautiful?
--Zachris Topelius
Training a telescope on one’s own belly button will only reveal lint. You like that? You go right on staring at it. I prefer looking at galaxies.
-- Sarah Hoyt
|
|
|
|
|
Why try to penalize and educate the end user for the sins of a poor coder?
|
|
|
|
|
Because the next person the poor program sees after the end user is Jesus.
Edit:
The language is JavaScript. that of Mordor, which I will not utter here
This is Javascript. If you put big wheels and a racing stripe on a golf cart, it's still a f***ing golf cart.
"I don't know, extraterrestrial?"
"You mean like from space?"
"No, from Canada."
If software development were a circus, we would all be the clowns.
|
|
|
|
|
What's more disturbing is that C# still doesn't allow this:
if (!someObj) {...}
which would preclude them from having to come up with the bullsh|t "?" operator.
".45 ACP - because shooting twice is just silly" - JSOP, 2010
- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010
- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
modified 27-Jul-16 8:23am.
|
|
|
|
|
John Simmons / outlaw programmer wrote: bullsh|t "?" operator More like boolsh|t in this case.
The language is JavaScript. that of Mordor, which I will not utter here
This is Javascript. If you put big wheels and a racing stripe on a golf cart, it's still a f***ing golf cart.
"I don't know, extraterrestrial?"
"You mean like from space?"
"No, from Canada."
If software development were a circus, we would all be the clowns.
|
|
|
|
|
If you implement the true[^] and false[^] operators, you can do something like:
if (someObj) { ... }
but you can't do:
if (!someObj) { ... }
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
The new approach (v6.0) is the null conditional operator, so you don't need to check for null.
someObj?.DoStuff();
|
|
|
|
|
I think that's what JSOP was referring to as the "bullsh|t operator".
#SupportHeForShe
Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson
You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun
|
|
|
|
|
Oops, I missed that. Sorry.
|
|
|
|
|
Often, in cases like that, you could very well add a comment indicating why the ojbect reference would be null (or non-null). Not always, but often.
When studying code written by others, one of the questions I frequently as myself is of the kind "OK, so I understand that you can't Do Stuff on a null object, but in which cases is the object null?? A short end-of-line comment such as 'null if child hasn't been named yet' or 'null if cleanup actions are already performed' can be worth their weight in gold.
|
|
|
|
|
On the other hand, I most definitely hate the (much too common) C construct 'while (1) {...}'
In embedded code, you frequently have infinite loops, and in some software I was handling, I declared a const bool WW3 = false, and changed the loop to 'while (!WW3) {...}'. That really upset one of the other programmers, who edited it back to 'while (1)' with some really nasty comments in the SVN log.
I tried to adopt the CHILL idea: In CHILL, 'EVER' is a reserved word, and the 'official' way of writing an infinite loop is 'DO FOR EVER [...]'. So I set up a '#define ever ;;' so that I could write (in C) 'for (ever) {...}'. But even that was too much for this other programmer; he insisted that 'while (1)' is The Professional Way of writing an infinite loop. I let him have his will.
|
|
|
|
|
I have found that "50 Specific Ways to Improve Your C#" is really good, and one of the things that the author Bill Wagner points out is that your code should be self explanatory, and not require much in comments. Good variable names helps a lot.
|
|
|
|
|
And good function names/class names. And a alear breakdown of code into bitesized pieces. Aptly named.
#SupportHeForShe
Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson
You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun
|
|
|
|
|
Yes. That and using good encapsulation. On one project they passed all 3-d point vectors as separate arguments. They also had 1000+ line methods.
|
|
|
|
|
The company I worked for, many years ago, had to deliver to a valued customer a pre-relase of the new and completely rewritten Fortran compiler: The old compiler could only handle 99 arguments to a function, and this customer had crossed that limit. The new compiler handled 127 arguments, but extending it to 255 arguments was a simple matter.
Another company I worked for had to update their linker program: The table of symbols defined and exported by a module could hold only 32767 elements. The customer crossed that limit. By changing the declaration of an index variable from signed to unsigned 16-bit, the linker could handle 65535 exported symbols. I believe the customer never crossed that limit - even though the software had a struct declaration of approx 8300 lines .
|
|
|
|
|
Very hard to believe that people would even consider using 50 arguments. When I get a lot of elements I quite often will just set properties since that is easier to keep track of. When I had to pass a lot of data, I would put it in an object and pass the object. When using something like a state pattern I generally have a common area so all states can access common data. I do know that a lot of COM calls can have a lot of arguments, but that is pretty old stuff now.
|
|
|
|
|
Sure, but remember that Fortran in the 1980s didn't have anything remotely resembling an "object" concept - not even anything struct-like. The Fortran you see today has very little to do with Fortran in the second millenium. When the battles around Fortran77 was being with a lot of very far-reaching extension proposals, old guru C. A. Hoare remarked that "I don't know what programming languages will look like in year 2000, but they will be called 'Fortran'!" He ended up being right: When I first time saw a Fortran 2003 program, I honestly didn't recognize it as Fortran at all!
The common way of transferring a lot of values to a function was COMMON. A COMMON block was a named, static, unstructured/typeless block of memory. Each user of the COMMON block had his own definition of it - the order and type of variables etc. Think of it as a shared typeless pointer where each module casts the typeless block to whatever it wants (but the block was static, not heap allocated). Of course any sensible system designer would make one set of definitions, to be copied into all modules, but "include"-like compiler directives where not that common then. So if the layout was changed (say, another variable added), the change had to be duplicated in all source files.
With statically allocated COMMON blocks as the only viable alternative, and no struct-mechanisms available, it really isn't that surprising that argument lists could grow terribly long.
|
|
|
|
|
Unfortunately I do remember FORTRAN 77. It has been so long since I worked with it. I even remember working with the earlier FORTRAN. I think I remember a book called 10 statement FORTRAN that I used. I was not enamored with FORTRAN 77 mainly because it seemed like some Computer Scientists had gotten hold of it and added all this stuff for making it a general purpose programming language and not extending the math capabilities. The one thing that FORTRAN had that made it special was handling of Complex Numbers. I thought that it should have been extended to handle arrays--There were already other languages available for general programming.
|
|
|
|
|
Maybe I misunderstand what you are saying: Fortran always handled arrays, at least from Fortran 2, with 1-based indexing.
One fun detail: This 16 bit minimachine (that is, the size of a full height fridge) I was working with in the early 1980s used a 3-word (i.e. 48 bits) floating point format. The machine had an instruction called MIX3, which decremented the value in the accumulator and then multiplying by 3. MIX3 was tailor made for changing the "logicial" (1-based, 48 bits) Fortran index into a "physical" (0-based, 16-bit word) memory address. If you worry about tne "multiplication" being time consuming: It really was an addition of the accumulator, shifted one bit up, to itself, so it was faster than an ordinary add (which required an operand access).
Yes, other languages were available - Pascal dates back to 1970, and honestly: From a language design point of view, it is far, far better than the entire C group of languages. (However, it failed in system programming ascpects; a standard Pascal program resided in a single source file. If the standard had included modularization concepts, it should have beaten C to the ground...).
What kept Fortran up for so long was "the same old story": Legacy code. Fortran IV was The Standard for offering open source code (open source did NOT start with Linux!). ACM offered a huge collection of several thousand Fortran IV functions for every imaginable mathematical, engineering, or otherwise scientific, operation. I even worked on a machine whose operating system was written in Fortran (in the days when it was considered 'impossible' to write an OS in anything but assembler).
I think of old Fortran with no regrets or complaints, and enjoy all those jokes and ways of speech that came out of Fortran. Like "You can program Fortran in any programming language" (to refer to unstructured, bad code). Or "God is real, unless explictly declared integer". And then the beauty from a Xerox Fortran programming manual: "The primary purpose of the DATA statement is to give names to constants; instead of referring to pi as 3.141592653589793 at every appearance, the variable PI can be given that value with a DATA statement and used instead of the longer form of the constant. This also simplifies modifying the program, should the value of pi change".
|
|
|
|
|