why does IndexOf still return -1

  • Thread starter Thread starter Gordon Cowie
  • Start date Start date
In general I agree with you about using "magic return values" to
indicate special situations. However, in this case I think it's the
best design out of the available alternatives.

I'm going to go out on a limb and postulate that any design involving
returning a special code that is the same datatype as the normal result
to not be the best design.

It's the oldest design. Maybe the simplest. Definitely the widest in use.

C# is full of great design philosophies that we conform to in the
journey to write better code. I really don't have a huge problem with
the way IndexOf works (I hardly use it), just using it to spur
discussion as I thought there would be interest from some "code purist"
C# lovers here.
 
Well, then we disagree on the definition of "best". :-)

I used to be a code purist, but in my old age I've become a pragmatist.
Sometimes conceptually pure frameworks lead to ugly, twisted
application code. Sometimes hacks in the underlying framework lead to
simpler applications (and thus cheaper to build and maintain).

Most of the time neither of these applies: elegant frameworks lead to
simple, elegant application code. However, 'tis not always so.

These days, my definition of "best design" = "inexpensive to maintain".
Other definitions may vary. :-)
 
Gordon Cowie said:
I see. Also, from reading other's replies. The real issue is the "cost"
related to exceptions. If they were free I think it would make for a much
cleaner coding style. Probably even anywhere a special return code is
returned.

try
{
x = s.IndexOf('x');
}
catch( Exception e )
{
// how is it clear that this relates to the indexing?
}

v

x = s.IndexOf('x');
if( x < 0 )
{
}
else
{
}

Worse yet you just know that you are going to find a load of code like:

try
{
x = s.IndexOf('x');
}
catch {}
Another negative about -1. It forces IndexOf to return an int, when a uint
would be more appropriate. The max length of the string is effectively cut
in half in order to provide space for the possible -1 result.

uint is not CLSCompliant so it's never going to happen.

If you have strings of over 2GB then indexing will be the least of your
problems.

P.S. In my opinion they should at least have provided

public const int NotFound = -1;

I'm not a fan of magic numbers even for error returns.
 
Gordon Cowie said:
I'm going to go out on a limb and postulate that any design involving
returning a special code that is the same datatype as the normal result
to not be the best design.

It's the oldest design. Maybe the simplest. Definitely the widest in use.

C# is full of great design philosophies that we conform to in the
journey to write better code. I really don't have a huge problem with
the way IndexOf works (I hardly use it), just using it to spur
discussion as I thought there would be interest from some "code purist"
C# lovers here.

Let's consider another example - TextReader.ReadLine. Should that throw
an exception instead of returning null when it has reached the end of
the stream? That would break the common idiom of:

string line;
while ( (line=reader.ReadLine()) != null)
{
...
}

- and it would break it without any significant benefit in my opinion.

If indeed using a special return code *is* the simplest design - and
ends up with the simplest client code - then that's probably the best
design, IMO. If most uses of the call work most easily when IndexOf
returns -1, where is the actual benefit of making it throw an exception
or forcing the use of an out parameter?
 
Jon Skeet said:
[snip]

Let's consider another example - TextReader.ReadLine. Should that throw
an exception instead of returning null when it has reached the end of
the stream? That would break the common idiom of:

string line;
while ( (line=reader.ReadLine()) != null)
{
...
}

[snip]

Admit it! Many of us would prefer the good old C/C++ idiom:

while( (line = reader.ReadLine()) )
{
//....
}

Yes - I know about the == bugs and I've done it myself but they always show
up before delivery so I'm willing to take my chances.

NB I always bracket the expression in these cases to indicate that I really
mean it. If I had my way the compiler would not warn if the expression was
bracketed.
 
Nick said:
[snip]

Admit it! Many of us would prefer the good old C/C++ idiom:

while( (line = reader.ReadLine()) )
{
//....
}

Well, "many" may do, but I know I wouldn't.
Yes - I know about the == bugs and I've done it myself but they always show
up before delivery so I'm willing to take my chances.

I prefer the explicit nature of things myself.
NB I always bracket the expression in these cases to indicate that I really
mean it. If I had my way the compiler would not warn if the expression was
bracketed.

I seem to remember that GCC does that...

Jon
 
Back
Top