简体   繁体   中英

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 something 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.

当代码明显错误以便修复它时编译器猜测程序员的意图是一个非常非常糟糕的主意。

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" (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"
            );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM