This chapter defines expressions and describes the operators provided by C#. It also explains how you can define the C# operators to work with your user-defined classes.
An expression is a string of operators and operands. Some of the constructs that can act as operands are
Literals
Constants
Variables
Method calls
Element accessors, such as array accessors and indexers
Other expressions
The C# operators take one, two, or three operands. An operator
Takes its operands as input
Performs an action
Returns a value, based on the action
Expressions can be combined, using operators, to create other expressions, as shown in this expression, with three operators and four operands:
Evaluating an expression is the process of applying each operator to its operands, in the proper sequence, to produce a value.
The value is returned to the position at which the expression was evaluated. There, it might in turn be an operand in an enclosing expression.
Besides the value returned, some expressions also have side effects, such as setting a value in memory.
Literals are numbers or strings typed into the source code that represent a specific, set value of a specific type.
For example, the following code shows literals of six types. Notice, for example, the difference between the double
literal and the float
literal.
static void Main() Literals { Console.WriteLine("{0}", 1024); // int literal Console.WriteLine("{0}", 3.1416); // double literal Console.WriteLine("{0}", 3.1416F); // float literal Console.WriteLine("{0}", true); // boolean literal Console.WriteLine("{0}", 'x'), // character literal Console.WriteLine("{0}", "Hi there"); // string literal }
The output of this code is the following:
1024 3.1416 3.1416 True x Hi there
Because literals are written into the source code, their values must be known at compile time.
Several of the predefined types have their own forms of literal:
Type bool
has two literals: true
and false
.
For reference type variables, literal null
means that the variable is not set to a reference in memory.
Integer literals are the most commonly used literals. They are written as a sequence of decimal digits, with
No decimal point
An optional suffix to specify the type of the integer
For example, the following lines show four literals for the integer 236. Each is interpreted by the compiler as a different type of integer, depending on its suffix.
236 // int 236L // long 236U // unsigned 236UL // unsigned long
Integer type literals can also be written in hexadecimal (hex) form. The digits must be the hex digits (0 through F), and the string must be prefaced with either 0x
or 0X
(numeral 0, letter x).
The forms of the integer literal formats are shown in Figure 8-1. Components with names in square brackets are optional.
The integer literal suffixes are listed in Table 8-1. For a given suffix, the compiler will interpret the string of digits as the smallest of the corresponding integer types that can represent the value without losing data.
For example, take the literals 236
and 5000000000
, neither of which has a suffix. Since 236
can be represented with 32 bits, it will be interpreted by the compiler as an int
. The larger number, however, will not fit into 32 bits, so the compiler will represent it as a long
.
Table 8-1. Integer Literal Suffixes
Suffix | Integer Type | Notes |
---|---|---|
None |
| |
|
| |
|
| Using the lowercase letter l is not recommended, as it is easily mistaken for the digit 1. |
|
| Using the lowercase letter l is not recommended, as it is easily mistaken for the digit 1. |
Literals for real numbers consist of the following:
Decimal digits
An optional decimal point
An optional exponent part
An optional suffix
For example, the following code shows various formats of literals of the real types:
float f1 = 236F; double d1 = 236.714; double d2 = .35192; double d3 = 6.338e-26;
The valid formats for real literals are shown in Figure 8-2. Components with names in square brackets are optional. The real suffixes and their meanings are shown in Table 8-2.
Real literals without a suffix are of type double
, not float
!
A character literal consists of a character representation between two single quote marks. A character representation can be any of the following: a single character, a simple escape sequence, a hex escape sequence, or a Unicode escape sequence.
The type of a character literal is char
.
A simple escape sequence is a backslash followed by a single character.
A hex escape sequence is a backslash, followed by an upper or lowercase x, followed by up to four hex digits.
A Unicode escape sequence is a backslash, followed by an upper or lowercase u, followed by up to four hex digits.
For example, the following code shows various formats of character literals:
char c1 = 'd'; // Single character char c2 = ' '; // Simple escape sequence char c3 = 'x0061'; // Hex escape sequence char c4 = 'u005a'; // Unicode escape sequence
Some of the important special characters and their encodings are shown in Table 8-3.