TaylorMichaelL said:
I disagree with your assessment of FxCop. Evidently enough people like it
because it is part of VS 2005. I do agree that blindly following its
rules
is not the correct answer but they address that themselves in the
documentation for the tool. It is of primary use to library writers like
Documenation isn't enough, if you take the number of people who read the
documentation and the number of people who just jump in and use it, I'd bet
you would have a difficult time fitting the ratio between the two in this
message. People don't read it and assume that the defaults are "how its
supposed to be".
I personally think FxCop has had the dubious honor of recommending things to
people that make no sense in the situation the person is actually in. Take
this Length == 0 thing, its stupid. Why? Because you have to do two
comparisons and make the expression a little more complex on the author and
subsequent readers for performance gains that will, in probably more than
99% of libraries, have as much visible effect as an ounce of salt would have
in Lake Michigan.
Over a benchmark of 1 million comparisons x == "" is not significantly
slower(about 70 milliseconds on a 400mhz, about 30 on my 2.0ghz), a big
chunk of time if you are writing a high-throughput xml parser or an html
renderer, but if you are just checking nameString to make sure someone typed
it in correctly, its not going to give you anything. Yet FxCop recommends
it, people follow it religiously, and you end up with oh so much more of
that premature optimization that performance yonks are always talking about.
Two comparisons coded to save less than a microsecond per comparison on a
400 mhz processor is ridiculous.
Of interest, if already interned, the fastest way to actually compare two
strings is by doing a reference comparison ( (object)x == (object)"" ). I'm
seeing an average of 20-30 milliseconds per 1 million comparisons that way
on my 2ghz.
myself that do not know ahead of time who their audience will be.
identify a lot of "design" flaws that are commonly made, such as new
protected members in a sealed class or non-private constructors in static
only classes. Some of these things the compiler could certainly figure
out
but "invisibly" making such a change could have unforeseen consequences.
Reflection comes to mind here. Of course it also is overjealous about
localization and IFormatProvider. I just turn these off. People have
been
using code review tools for decades. FxCop is just Microsoft's free
version.
That doesn't change that the tool recommends things that don't make sense
all too often and that it comes across as a verbatim "Microsoft
Recommendation." Advice given that is taken as a command is almost always
badly put advice.
The help on design flaws is nice, but I still think they could have done a
*MUCH* better job on the rules enabled by default and explaining themselves.
A tools worth is the net difference of those it helps and those it harms.
The help on design flaws doesn't outweigh the number of bad perceptions
FxCop has spread throughout developers in my mind.
I don't follow your comment on (value.Length == 0) and (value ==
String.Empty) not being equal. They are not "code-wise" equal (one being
an
int compare and the other calling a native comparer for the interned
strings)
but they are semantically equal. In both cases if the string is empty
they
are true and if the string is not empty they are false. The only real
difference is when the string is null. That is why the current
methodology
recommends (value == null) || (value.Length == 0). In 2.0 IsNullOrEmpty
will
remove the need for this conditional.
As a note, value == "" is *NOT* the same as (value == null) || (value.Length
== 0), it is closer to (value != null) && (value.Length == 0). You basically
have two different concepts
one set is
value == ""
and
value != null && value.Length == 0
these are true only if the value *is* ""(string.Empty), but not if it is
null or "a" or anything else
the other set,
value == null || value == ""
and
string.IsNullOrEmpty(value)
are true if value is ""(string.Empty) *OR* if it is null.
IsNullOrEmpty still has a different meaning than x == "", unquestionably.
The difference between null and blank is as important as the difference
between blank and "banana".
I also, personally, think that
if (x != null && x.Length == 0)
is pretty ugly, harder to type, offers more points of error, and more
complex to understand than just x == "" or x == string.Empty, and shouldn't
be used just to make FxCop happy or for non-existant performance reasons.
IsNullOrEmpty doesn't solve the problem as it is really an answer for a
different problem.
If there is no performance need, just a human cost, what sense does it make?