I would never hard code a call like this. string x = s.Substring(0, 999); // should return "test", not throw string x = s.Substring(0, -1 ); // should return Empty , not throw
That would be silly. However, these calls occur due to inline computation. string x = s.Substring(FindStart(...), FindEnd(...)); Let suppose that the function FindEnd() returns -1 because some delimiter is not found (like IndexOf()). I would prefer Substring to simple return Empty not throw. If Substring did *not* throw I could do this. string x = s.Substring(0, s.IndexOf('=') ).Trim().ToUpper(); I could count on Substring returning the *very reasonable* value of Empty if the token was not found. Since it does throw, I must do this. int i = s.IndexOf('='); string x; if (i > 0) x = s.Substring(0, i ).Trim().ToUpper(); else x = string.Empty; My point is... I see this little 'if' block every time I want to use Substring. It would be much more convenient if the Substring simply didn't throw. For the same reason that you don't want to be forced to do an 'if' block before every division. Just because everything doesn't throw an exception, that doesn't imply that we are returning to the bad old days. Consider StreamReader.ReadLine() for example. It returns null if you are at the end of the stream. It would not be as convenient to use 'in its typical application' if it threw an exception. Cheers...David ----- Original Message ----- From: "Ian Griffiths" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Monday, May 06, 2002 8:26 PM Subject: Re: [DOTNET] Why does Substring() throw? "David Ferguson" <[EMAIL PROTECTED]> wrote: > The fact that Substring() throws if any little parameter is > off makes it almost unusable. Don't you think? I disagree for the examples that you have shown: > string s = "test"; > string x = s.Substring(0, 999); // should return "test", not throw What's wrong with s.SubString(0); ? I think the use of 999 to indicate "longer than any string could ever possibly be" is extremely bad practice. Strings can easily be longer than 999 characters. If you mean "from here to the end of the string" then just say so - the String class provides you with a method for doing precisely that. Why feed in whacky constants and expect the framework to guess the required semantics when you can just say what you mean? > string x = s.Substring(0, -1 ); // should return Empty , not throw Why would you ever do this? Asking for a string of negative length is quite clearly a programming error, since no such thing can exist. The class is simply telling you this rather than attempting to guess what you might have meant if your code hadn't contained that programming error. If you want an empty string, say so. > string z = s.Substring(999, 4); // should return Empty , not throw This is the only case where I can see that it might conceivably be useful to get back nothing, since it would save you from having special handling to detect the case when you've run off the end of the string. On the other hand, what if running off the end of the string was an error? In that case I *would* require special handling, and would probably be cursing the string class for not doing it for me. And since for all the other cases it makes sense to throw an exception for attempting to access a non-existent part of a string, it is consistent for it to do so here. > I think it shouldn't throw for the same reason the division > by zero doesn't. It is just too much trouble to always test > every division. ...just like it's too much trouble to test the return value from every system call? Surely this it is the programmer's job to deal with this kind of thing - to ignore such things would be pure negligence. If there's an error case, the last thing I want is for the code to silently swallow it and press on regardless. That's how it was in the bad old days, and we changed for a good reason. C# raises a DivideByZeroException if you divide an integer by zero. Doesn't VB? Floating point numbers don't raise an exception admittedly - you get Infinity (or NaN if both numbers were zero). But for integers I want it to throw an exception since there is no reasonable integer result for dividing a number by zero. I'm not entirely happy that FP numbers don't throw here either actually, mostly because it means that I have to check every time I do a divide... So I disagree entirely with the philsophy behind what you are saying (assuming I have understood you correctly) - I think that if the system were silently to swallow errors, it would require *much* more effort on the programmer's part to write working code. Of course it would make it much easier to write flakey code. But I don't want to write flakey code. > You can't just do simple calculations and get the > substring because it might through. If it throws, it is because you have bad input. This means you should check your input. This is a basic requirement for any piece of code. Failure to check input is probably the single biggest cause of security holes in software systems. So I approve of anything that detects bad input and flags it as an error - it keeps me honest (i.e. I have no option but to check my input; since I should be doing that anyway if I want my code to be robust, it's a good thing that I have no option). I dislike anything that attempts to press on regardless in the fact of manifestly bad input. For these methods to behave as I believe you are suggesting rather smacks of On Error Resume Next... :-) -- Ian Griffiths DevelopMentor You can read messages from the DOTNET archive, unsubscribe from DOTNET, or subscribe to other DevelopMentor lists at http://discuss.develop.com. You can read messages from the DOTNET archive, unsubscribe from DOTNET, or subscribe to other DevelopMentor lists at http://discuss.develop.com.