简体   繁体   English

C#运算符和可读性

[英]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? 也许有一些逻辑可以说除非指定一个新的stringName,否则使用第一个?

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. 我认为你的提议会混淆表达式解析的规则 - 现在,'=='变成了一个quadreny(?)运算符,而不是二进制运算符。 I've found myself missing SQL's 'IN' operator, though, and've used something like this: 我发现自己错过了SQL的'IN'运算符,并且使用了类似这样的东西:

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. stringName == "firstName"返回一个布尔值。
"lastName" is a string literal. "lastName"是一个字符串文字。

|| 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? 但究竟什么是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. ,但stringName == firstName && lastName与上述逻辑不同,实际上没有意义。

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

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 . stringName == ("firstName" || "lastName")看起来好像要测试两个字符串的真实性,并且这些字符串总是为真,然后将该布尔结果与字符串stringName进行比较。

If you add parentheses like this (stringName == "firstName") || "lastName" 如果你添加这样的括号(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" . (stringName == "firstName") || "lastName" ,条件也总是如此,因为无论stringName是否等于"firstName""lastName"始终为true。

I like the Ruby way of doing it: 我喜欢Ruby的做法:

["firstName", "lastName"].include? stringName

You could always use Contains like others have suggested or write a String extension method to where you could do: 您可以像其他人一样建议使用Contains或者将String扩展方法写入您可以执行的操作:

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" . 如果您是第一次查看代码,并且您并未完全处于最佳状态,则可能无法立即看到您将stringName"firstName""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. 这只有在operator||(string,string)返回时才会起作用..一种字符串集合,你有一个Equals重载,它接受一个字符串和字符串集合,并验证字符串是否在集合中。 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: 我发现Contains()函数解决了这个问题,即:

string[] ValidNames = new string[] { "firstName", "lastName"};

if(ValidNames.Contains(stringName))
{
    //Do Code
}

I wouldn't mind a SQL like syntax of: 我不介意SQL语法如下:

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. 当FCL包含丰富的内容以创建在此主题中看到的各种各样的答案时,您不需要具有更灵活的C#语法,因为可读性很快就会成为您如何在所有丰富内容中创建答案的功能。 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"
            );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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