|
Declare it as a public or protected member.
Mazy
"If I go crazy then will you still
Call me Superman
If I’m alive and well, will you be
There holding my hand
I’ll keep you by my side with
My superhuman might
Kryptonite"Kryptonite-3 Doors Down
|
|
|
|
|
Hello all!
I have the following problem: I have some properties that must not be null. Therefore I thought I should throw an exception in the set accessor if a null value is passed. But what exception? I thought to throw ArgumentNullException but is this a good approach? It's intended to be used in methods after all...
Cheers
and any help appreciated
Martin
"Situation normal - all fu***d up"
Illuminatus!
|
|
|
|
|
I'd consider a value passed to a property to be an argument.
I tend to think that if you're giving a class invalid information, it's an Argument[Null/Invalid]Exception. If the class already holds invalid information based on what you're trying to achieve, it's an InvalidOperationException.
Paul
|
|
|
|
|
Thanks for the reassuring information !!
Cheers
have a sunny sunday
Martin
"Situation normal - all fu***d up"
Illuminatus!
|
|
|
|
|
Martin,
If you're not already, I would suggest following the conversation that extended in this thread - there's some interesting points being raised on both sides.
P
Paul
|
|
|
|
|
Yeah thanks, codeproject didn't "work" for about one day for me..
Cheers
Martin
"Situation normal - all fu***d up"
Illuminatus!
|
|
|
|
|
Someone else (or maybe you) was talking about this earlier in the Lounge (or maybe the Soapbox). CP has gone down, for an hour or so at a time, several times lately and then there's problems with losing the DNS entries but I didn't really follow it. It's not happening to me and my eyes tend to glass over when I hear anything about DNSes, so I phased out.
Paul
|
|
|
|
|
Exceptions are for exceptional conditions - conditions that are unexpected during normal circumstances. Exceptions are relatively expensive and aren't that great for stuff like this.
I personally would write the class to have a constructor that accepts all required arguments in addition to returning an error (or true/false) on execution of a method that finds a required field that contains null. Perhaps go as far as exposing a public read-only IsValid property and have your internal methods call it - exposing IsValid may also help developers understand how your class works since they can check the object's validity anytime they like.
If you insist on using exceptions, don't throw CLR exceptions(like System.ArgumentNullException - these are CLR-sourced exceptions. You can create your own application-specific exceptions based on the System.ApplicationException class - it exists for people like us to create our own exceptions. Just create your own class and derive it from System.ApplicationException - you don't have to add any members since the catch statement works based on the exception's type.
Erik Westermann
Author, Learn XML In A Weekend (October 2002)
|
|
|
|
|
Erik Westermann wrote:
Exceptions are for exceptional conditions - conditions that are unexpected during normal circumstances.
Wouldn't you say that trying to set something to null that shouldn't ever be null is an exceptional circumstance? The application setting the property SHOULD check for null before setting. If it doesn't then there's nothing wrong with throwing an exception.
I would agree with you that applications shouldn't simply live inside a try/catch structure, just in case. But if a class/component/control receives something it doesn't expect from an app then it should throw an exception.
Erik Westermann wrote:
If you insist on using exceptions, don't throw CLR exceptions(like System.ArgumentNullException - these are CLR-sourced exceptions. You can create your own application-specific exceptions based on the System.ApplicationException class - it exists for people like us to create our own exceptions.
Why would you do that if one already exists that meets the criteria you're looking for? Do things in the Microsoft namespace avoid throwing exceptions from the System namespace?
I'm not meaning to sound argumentative, I'm genuinely interested in people's opinions of good programming practice. The .NET languages are new enough that there is room for discussion; while some things will carry naturally from older languages, I'm not sure exceptions do. They have existed before but not in the same manner they do here.
Paul
|
|
|
|
|
Paul Riley wrote:
Wouldn't you say that trying to set something to null that shouldn't ever be null is an exceptional circumstance?
Have you come across the two pronged plugs that plug into the wall only one way? One prong of the plug is keyed and so is the wall receptacle so that the prong must match the wall receptacle's orientation - this is done to prevent something from being plugged in backwards.
The person that designed the plug expected that someone would eventually try to put the plug into the receptacle the wrong way and took measures to ensure the chances of that happening are much smaller than if he did not design the plug with that possibility in mind. My point is that the plug's designer knew that this could be a problem and wants to prevent the device that's being plugged in from working when the plug is put in the wrong way - this is obviously an expected condition.
I view this scenario the same way - since it is possible to set a property to null and the class requires a non-null value - this is nothing exceptional.
Paul Riley wrote:
Why would you do that if one already exists that meets the criteria you're looking for?
Simply becasue the idea of the .NET Platofrm is to provide a space where all activities occur in a managed, type-safe environment. The System namespace is called "system" becuase it exposes classes that you can use to interact with the "system". If your applicaiton throws an exception, throw an applicaiton-specific exception that's derived from System.ApplicationException to avoid confusion with CLR-generated exceptions.
Moreover, CLR-based exceptions usually need to be dealt with in another way than do application-specific exceptions. For example, if the CLR throws an OutOfMemoryException, you'll have to deal with that differnetly than if an application throws it's own memory-specific exception. In the application's case, the problem could be the result of some fixed capacity buffer becomming full whereas the CLR-based exception obviously indicates a problem that affects the entire system.
Given that the System.ApplicationException class is a derivitave of System.Exception, a catch block that catches a System.Exception type will also catch System.ApplicationException exceptions, thus reducing the chance that an applicaiton-specific exception could be missed.
Erik Westermann
Author, Learn XML In A Weekend (October 2002)
|
|
|
|
|
Erik Westermann wrote:
Have you come across the two pronged plugs that plug into the wall only one way? One prong of the plug is keyed and so is the wall receptacle so that the prong must match the wall receptacle's orientation - this is done to prevent something from being plugged in backwards.
Thank god I've been electrocuted enough times in the US to have the faintest idea what you're talking about... our plugs here in the UK are a sensible three-prong design (one vertical, two horizontal) and there's no way on earth anyone's plugging that in the wrong way around!
Erik Westermann wrote:
The person that designed the plug expected that someone would eventually try to put the plug into the receptacle the wrong way and took measures to ensure the chances of that happening are much smaller than if he did not design the plug with that possibility in mind.
I would argue that this is exactly what the programmer is trying to do in this example. Someone, eventually, is going to pass null to that property and is not going to call IsValid().
Thus the class designer has to check IsValid all over his own class before doing anything with that property and may still have to throw an exception if this causes a situation that is unacceptable. Not only is this inefficient but it's harder for the app programmer to debug.
Erik Westermann wrote:
this is nothing exceptional
I think to a point this is where our opinions part. You are taking "Exception" in the context of "This is an exception to the rule", I think an "Exception" is better described in the context of the program saying "I take exception to this scenario".
Erik Westermann wrote:
Simply becasue the idea of the .NET Platofrm is to provide a space where all activities occur in a managed, type-safe environment. The System namespace is called "system" becuase it exposes classes that you can use to interact with the "system".
If that were true, why are the fundamental base classes all set in the System namespace? Wouldn't Object and Exception be better placed in a "Core" namespace?
However, I do see an argument (although you never quite said this, I think it was your point) that ArgumentNullException is derived from System.SystemException and if someone is trying to catch system-based problems, they will also catch a program defined ArgumentNullException.
That could be a problem, but I would suggest that trying to catch SystemExceptions like this is a problem in and of itself.
For example, RegistryKey.DeleteSubKeyTree will throw an ArgumentNullException if you pass null instead of a string. To argue that this is a system-level exception is ridiculous, just because the registry is part of the system, it must be an application error that caused the problem.
Paul
|
|
|
|
|
Paul Riley wrote:
I think an "Exception" is better described in the context of the program saying "I take exception to this scenario".
It really depends on what you're designing and what its purpose will be. I'm speaking in the snese of who the immediate user is of course. For example, if you're building a class library, you'll probably end up throwing exceptions since you may have no other means of reporting an error or the best way to handle the error is to let the code that called the code in the class library handle the error.
If you're building an applicaiton or a component that an end user will use then it is probably not a good idea to throw an exception since most typical end users don't know what to do when something 'wierd' happens.
Paul Riley wrote:
Wouldn't Object and Exception be better placed in a "Core" namespace?
That was Microsoft's choice.
Paul Riley wrote:
To argue that this is a system-level exception is ridiculous
It is a system-level exception, System.ArgumentNullException is a derivative of System.SystemException. The naming standard appears to focus on the source of the exception, not the entity that casued it.
Erik Westermann
Author, Learn XML In A Weekend (October 2002)
|
|
|
|
|
Erik Westermann wrote:
It really depends on what you're designing and what its purpose will be. I'm speaking in the snese of who the immediate user is of course. For example, if you're building a class library, you'll probably end up throwing exceptions since you may have no other means of reporting an error or the best way to handle the error is to let the code that called the code in the class library handle the error.
I'd agree with you on both a class and an applicaton. Applications should avoid using Exceptions, though I admit I've been guilty of throwing an exception because I'm in the middle of a try block and want to act the same in the event of this error as I would if it were an exception.
That was, however, an ApplicationException.
I wouldn't agree with you in the case of a component - I don't see how this is different from a class library.
Erik Westermann wrote:
That was Microsoft's choice.
Sure, but it does show a total disregard for the selection of the namespace name "System". I feel you're taking that name a lot more seriously than those who designed it.
Erik Westermann wrote:
It is a system-level exception, System.ArgumentNullException is a derivative of System.SystemException. The naming standard appears to focus on the source of the exception, not the entity that casued it.
Except that an ArgumentNullException is NEVER going to be a result of a system problem, it's ALWAYS going to be a result of erroneous programming.
Thus, trying to catch system problems specifically simply by using catch (System.SystemException ex) is already a dangerous idea.
As Martin has pointed out, what if (for some reason I can't think of right now) you wanted to catch all exceptions caused by null arguments? Is it not unfair to expect people to catch the standard ArgumentNullException plus your ArgumentNullException plus my ArgumentNullException, etc, etc?
Paul
|
|
|
|
|
Now I have used exceptions instead of events, and will make no further comment
Bottom line, you use it where u need it
Paul Riley wrote:
Is it not unfair to expect people to catch the standard ArgumentNullException plus your ArgumentNullException plus my ArgumentNullException, etc, etc?
Say what ? So you say its OK to expect ppl to check for 3 exceptions instead of one, although they check for the same thing? PUDATE: Me dyslexic mind didnt read that right.
|
|
|
|
|
leppie wrote:
Now I have used exceptions instead of events, and will make no further comment
Now that is shoddy coding
leppie wrote:
Say what ? So you say its OK to expect ppl to check for 3 exceptions instead of one, although they check for the same thing? PUDATE: Me dyslexic mind didnt read that right.
But that's exactly what Erik is suggesting, on the grounds that otherwise anyone trying to catch system-level exceptions will accidentally catch your ArgumentNullexception.
Paul
|
|
|
|
|
Paul Riley wrote:
Now that is shoddy coding
Not if you use it correctly. For example, to abort a thread at a precise point and raise an "event".
|
|
|
|
|
leppie wrote:
Not if you use it correctly. For example, to abort a thread at a precise point and raise an "event".
It still sounds like a dodgy idea. What if something else in the try block throws an exception for another reason? I suppose it's possible to make sure that doesn't happen.
I assume you're trying to kick out of a loop? Isn't there a better way, like "break"?
Just thinking aloud. It strikes me that there should be a way to do this without using an exception, but maybe not. (tell me to stop being nosey, if you want )
Paul
|
|
|
|
|
Paul Riley wrote:
I assume you're trying to kick out of a loop? Isn't there a better way, like "break"?
Probably, but I needed to send some arguements with the "event", and this was the quickest thing that came to mind. The nice thing is I didnt have to implement an event or had to add/remove a handler. Only a try/catch, for when (if) it happens.
|
|
|
|
|
Fair enough.
Let me put it this way: I used to work with COBOL and some of the worst code I've ever seen was as a direct result of people trying at all costs to avoid using GO TO.
I mean okay, I understand why GO TO is considered tacky but in COBOL at times it can be absolutely necessary because there aren't any other construct-breakers.
So I do accept that sometimes what may be considered tacky is actually the neatest thing to do.
I will say this though: don't avoid implementing events. Once you've done two or three, you get used to them and you can knock them together in a couple of minutes. I love events
Paul
|
|
|
|
|
OK, I do agree, events are the nicer way, but if a tree falls in the forest when nobody's there to hear it, will it make a sound? The was just to test some thing quick(and dirty). I dont I will every let people see such a thing.
Paul Riley wrote:
Once you've done two or three, you get used to them and you can knock them together in a couple of minutes.
Unfortunately, most people can do events, but have no idea what is happening under the hood. Once you understand delegates though, things do become very clear and easy.
|
|
|
|
|
leppie wrote:
OK, I do agree, events are the nicer way, but if a tree falls in the forest when nobody's there to hear it, will it make a sound?
Yes.
leppie wrote:
Unfortunately, most people can do events, but have no idea what is happening under the hood. Once you understand delegates though, things do become very clear and easy.
Absolutely true. It's one thing to copy it out of a book as I did with my first event, it's something else entirely to figure out what a delegate is and use it properly.
It really is a surprisingly simple concept when you get your head around it though (surprising because it took me hours to understand it but then when I did I wondered why it took me so long).
Paul
|
|
|
|
|
Paul Riley wrote:
Yes.
Actually its "No".
bool ProveTreeQuestion(PersonsInForest persons)
{
foreach (Person person in persons)
{
if (person.Hear()) return true;
}
return false;
}
Now if persons.Count = 0, the result will allways be false.
|
|
|
|
|
Erik Westermann wrote:
Simply becasue the idea of the .NET Platofrm is to provide a space where all activities occur in a managed, type-safe environment. The System namespace is called "system" becuase it exposes classes that you can use to interact with the "system". If your applicaiton throws an exception, throw an applicaiton-specific exception that's derived from System.ApplicationException to avoid confusion with CLR-generated exceptions.
But wouldn't this be a problem in itself? Let's say you write a program, that uses class libraries from two or three different vendors and each throws a different kind of exception if the exact same condition (an argument is set to null for example) is met? Wouldn't this be a bad design, too? And why is it more exceptional if you pass an invalid "null" argument to a clr function than to a function of a third party library? I see the point with the out of memory exception - that sure is some kind of "system exception". But ArgumentNullException and ArgumentOutOfRange exception? Actually I never thought about these problems (Visual C# step by step at least uses these two exceptions in user code) - only wether it is the right exception to be thrown from a set accessor.
Cheers
and thanks for your answers
Martin
"Situation normal - all fu***d up"
Illuminatus!
|
|
|
|
|
Martin Häsemeyer wrote:
Wouldn't this be a bad design, too?
How so? You know the exact nature of the problem based on the exception's type. Besides, all exceptions are derivatives of System.Exception; as a result, if you code your catch blocks properly, you'll be able to handle errors from both libraries in this scenario.
Martin Häsemeyer wrote:
And why is it more exceptional if you pass an invalid "null" argument to a clr function than to a function of a third party library?
It isn't. It depands on what the class' designer is atembpting to achieve. An exception is designed to, ultimately, halt your code if it is allowed to 'bubble up' through to the system regardless of what type of exception gets thrown. Exceptons are non-local control structures that let you centralize error handling in one part of your application as opposed to having you sprinkle if statements throughout your code. In some cases; however, it is more approprate a number of cases to use a less computationally expensive means of handling an error.
Erik Westermann
Author, Learn XML In A Weekend (October 2002)
|
|
|
|
|
"An exception is the violation of a programmatic interface's implicit assumptions"
Jeffrey Richter, Applied Microsoft .NET Framework Programming.
He goes on to detail that he believes exceptions should be used for more than just "rare" occurances.
Jared
jparsons@jparsons.org
www.prism.gatech.edu/~gte477n
|
|
|
|