Professional C# 6 and .NET Core 1.0. Christian Nagel
Чтение книги онлайн.
Читать онлайн книгу Professional C# 6 and .NET Core 1.0 - Christian Nagel страница 22
The output from this is as follows:
Changing the value of s1 has no effect on s2, contrary to what you’d expect with a reference type! What’s happening here is that when s1 is initialized with the value a string, a new string object is allocated on the heap. When s2 is initialized, the reference points to this same object, so s2 also has the value a string. However, when you now change the value of s1, instead of replacing the original value, a new object is allocated on the heap for the new value. The s2 variable still points to the original object, so its value is unchanged. Under the hood, this happens as a result of operator overloading, a topic that is explored in Chapter 8. In general, the string class has been implemented so that its semantics follow what you would normally intuitively expect for a string.
String literals are enclosed in double quotation marks ("."); if you attempt to enclose a string in single quotation marks, the compiler takes the value as a char and throws an error. C# strings can contain the same Unicode and hexadecimal escape sequences as chars. Because these escape sequences start with a backslash, you can’t use this character unescaped in a string. Instead, you need to escape it with two backslashes (\\):
Even if you are confident that you can remember to do this all the time, typing all those double backslashes can prove annoying. Fortunately, C# gives you an alternative. You can prefix a string literal with the at character (@) and all the characters after it are treated at face value; they aren’t interpreted as escape sequences:
This even enables you to include line breaks in your string literals:
In this case, the value of jabberwocky would be this:
C# 6 defines a new string interpolation format that is marked by using the $ prefix. You’ve previously seen this prefix in the section “Working with Variables.” You can change the earlier code snippet that demonstrated string concatenation to use the string interpolation format. Prefixing a string with $ enables you to put curly braces into the string that contains a variable – or even a code expression. The result of the variable or code expression is put into the string at the position of the curly braces:
NOTE Strings and the features of string interpolation are covered in detail in Chapter 10, “Strings and Regular Expressions.”
This section looks at the real nuts and bolts of the language: the statements that allow you to control the flow of your program rather than execute every line of code in the order it appears in the program.
Conditional Statements
Conditional statements enable you to branch your code depending on whether certain conditions are met or what the value of an expression is. C# has two constructs for branching code: the if statement, which tests whether a specific condition is met, and the switch statement, which compares an expression with several different values.
The if Statement
For conditional branching, C# inherits the C and C++ if.else construct. The syntax should be fairly intuitive for anyone who has done any programming with a procedural language:
If more than one statement is to be executed as part of either condition, these statements need to be joined into a block using curly braces ({.}). (This also applies to other C# constructs where statements can be joined into a block, such as the for and while loops):
If you want to, you can use an if statement without a final else statement. You can also combine else if clauses to test for multiple conditions (code file IfStatement/Program.cs):
There is no limit to how many else ifs you can add to an if clause.
Note that the previous example declares a string variable called input, gets the user to enter text at the command line, feeds this into input, and then tests the length of this string variable. The code also shows how easy string manipulation can be in C#. To find the length of input, for example, use input.Length.
Another point to note about the if statement is that you don’t need to use the braces when there’s only one statement in the conditional branch:
However, for consistency, many programmers prefer to use curly braces whenever they use an if statement.
TIP Not using curly braces with if statements can lead to errors in maintaining the code. It happens too often that a second statement is added to the if statement that runs no matter whether the if returns true or false. Using curly braces every time avoids this coding error.
A good guideline in regard to the if statement is to allow programmers to not use curly braces only when the statement is written in the same line as the if statement. With this guideline, programmers are less likely to add a second statement without adding curly braces.
The if statements presented also illustrate some of the C# operators that compare values. Note in particular that C# uses == to compare variables for equality. Do not use = for this purpose. A single = is used to assign values.
In C#, the expression in the if clause must evaluate to a Boolean. It is not possible to test an integer directly (returned from a function, for example). You have to convert the integer that is returned to a Boolean true or false, for example, by comparing the value with zero or null:
The switch Statement
The switch / case statement is good for selecting one branch of execution from a set of mutually exclusive ones. It takes the form of a switch argument followed by a series of case clauses. When the expression in the switch argument evaluates to one of the values beside a case clause, the code immediately following the case clause executes. This is one example for which you don’t need to use curly braces to join statements into blocks; instead, you mark the end of the code for each case using the break statement. You can also include a default case in the switch statement, which executes if the expression doesn’t evaluate to any of the other cases. The following switch statement tests the value of the integerA variable:
Note that the case values must be constant expressions; variables are not permitted.
Though the switch.case statement should be familiar to C and C++ programmers, C#’s switch.case is a bit safer than its C++ equivalent. Specifically, it prohibits fall-through conditions in almost all cases. This means that if a case clause is fired early on in the block, later clauses cannot be fired unless you use a goto statement to indicate that you want them fired, too. The compiler enforces this restriction by flagging every case clause that is not equipped with a break statement as an error: