C# Operators and readability
I was just working on some code and caught myself making this error
if (stringName == "firstName" || "lastName")
// Do code
obviously this is wrong and should be
if (stringName == "firstName" || stringName == "lastName")
// Do code
but it just got me thinking in regards to readability would the first be easier? Maybe having some logic that could say unless a new stringName is specified, use the first one?
Really not a question, Im just curious if there is s开发者_JS百科omething I dont fully comprehend on the logic behind compiling a statement like this.
I think your proposal would muddy the rules of expression parsing - now, the '==' becomes a quadreny (?) operator, rather than a binary one. I've found myself missing SQL's 'IN' operator, though, and've used something like this:
if (stringName.In("foo", "bar", "baz"))
{
}
// in an extension method class
public static bool In<T>(this T value, params T[] values)
{
return values.Contains(value);
}
The problem is that if works on booleans.
stringName == "firstName"
returns a boolean.
"lastName"
is a string literal.
||
is a short-circuited boolean or operator that takes booleans on both sides.
In other words, you want to change the definition of ||
which is generally a bad idea.
In theory, you could have the parser infer what you mean... but that becomes ambiguous very quickly.
if (stringName == firstName || lastName)
Looks OK, right? But what exactly is lastName?
What if I did this?
const bool lastName = false;
Also, &&
is the opposite of ||
, but stringName == firstName && lastName
isn't the opposite of the above logic, and in fact wouldn't make sense.
Having the compiler guess at the programmer's intention when the code is clearly wrong in order to fix it is a really, really bad idea.
Even with parentheses, it doesn't make sense. stringName == ("firstName" || "lastName")
looks like you want to test the truth of the two strings, and those strings are always going to be true, and then compare that Boolean result with the string stringName
.
If you add parentheses like this (stringName == "firstName") || "lastName"
, the condition is also always going to be true, since "lastName"
is always true regardless of whether or not stringName
equals "firstName"
.
I like the Ruby way of doing it:
["firstName", "lastName"].include? stringName
You could always use Contains
like others have suggested or write a String extension method to where you could do:
stringName.EqualsOneOf(new[] {"firstName", "lastName"})
The reason they did not allow such syntax was most likely because of readability. If you're looking at the code for the first time, and you're not exactly in your best state of mind, you might not see immediately that you're comparing stringName
to both "firstName"
and "lastName"
. It just makes your intentions that much more defined.
Then again, parentheses might solve that.
That would only work if operator||(string,string)
returned.. a sort of collection of strings and you had an Equals
overload that took a string and that collection of strings and verified that the string is in the collection. Seems like a lot of work done behind the scenes for a very rarely used construct.
Especially since you already can do something like:
if(new string[]{"firstName","lastName"}.Contains(stringName))
// code
I find the Contains() function solves this problem ie:
string[] ValidNames = new string[] { "firstName", "lastName"};
if(ValidNames.Contains(stringName))
{
//Do Code
}
I wouldn't mind a SQL like syntax of:
if(stringName in ("firsName", "lastName"))
{
}
This is why, as a habit, I always do:
if ((stringName == "firstName") || (stringName == "lastName"))
// Do code
After a while it becomes second nature.
When the FCL contains the richness to create the sheer variety of answers seen in this thread, you don't need to have a more flexible C# syntax because readability soon becomes a feature of how you create the answer amongst all the richness. It boils itself down to choices between method and object calls much of the time.
Here's an example (just another of many) of being able to locate one or multiple strings simultaneously in an array of strings, or to apply any other criteria you see fit to that set of strings. Indentation, spacing and code comments play a big part for understanding this code sample, as for any code.
bool found = Array.Exists(
// array of strings to search
new[] { "c#", ".net", "programming", "design patterns", "work", "play", "bits", "bytes", "break" },
// criteria - can even satisfy multiple conditions simultaneously if desired
str => (str == ".NET" || str == "work") //look for ".NET" or "work"
);
精彩评论