0% found this document useful (0 votes)
23 views88 pages

2 C# Core Language Features

Uploaded by

beastfoam
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
23 views88 pages

2 C# Core Language Features

Uploaded by

beastfoam
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 88

C# Core Language Features

• Natural and programming languages consist of both


simple and complex structures.
• The complex structures can be decomposed into simple
elements.
• When learning a new natural language, you probably
wouldn't start with a review of sentence structure.
• Instead, you probably would begin with an exploration
of nouns, verbs, and the simpler components of the
language.
• For C#, the simpler components are symbols, tokens,
white space, punctuators, comments, preprocessor
statements, and other elements.
Symbols and Tokens

• Symbols and tokens are the basic constituents


of the C# language.
• Sentences are composed of spaces, tabs, and
characters.
• Similarly, C# statements consist of symbols
and tokens.
C# Symbols and Tokens

• Description Symbols or Tokens


• White space Space
• Tab Horizontal_tab, Vertical_tab
• Punctuator ,:;
• Line terminator carriage_returns
• Comment // /* */ /// /**
• Preprocessor directive #
• Block {}
• Generics <>
• Nullable Type ?
• Character Unicode_character
• Escape character \code
• Numeric Suffix f d m u l ul lu
• Operator +, -, >, <, *, ??, () and so on
• White Space
• White space is defined as a space, horizontal
tab, vertical tab, or form feed character.
• White space characters can be combined;
where one character is required, two or more
contiguous characters of white space can be
substituted.
• Where white space is permitted, one or more
instances of white space are allowed.
• Tabs
• Tabs—horizontal and vertical—are white
space characters..
• Punctuators
• Punctuators separate and delimit elements of
the C# language.
• Punctuators include the semicolon (;), dot (.),
colon (:), and comma (,).
• Semicolon punctuator
• In a natural language, sentences consist of phrases
and clauses and are units of cohesive expression.
• Sentences are terminated with a period (.).
• Statements consist of one or more expressions and
are the commands of the C# programming
language.
• Statements are terminated by a semicolon (;).
• C# is a free-form language in which a statement can
span multiple lines of source code and start in any
position.
• Conversely, multiple statements can be combined
on a single source code line, assuming that each
statement is delimited by a semicolon.
• Dot punctuator
• Dot syntax connotes membership.
• The dot character (.) binds a target to a member, in
which the target can be a namespace, type,
structure, enumeration, interface, or object.
• This assumes the member is accessible.
• Membership is sometimes nested and therefore
described with multiple dots.
• Dot punctuator: Target.Member
• This is an example of the dot punctuator:
System.Windows.Forms.MessageBox.Show("A
nice day!")
Colon punctuator
• The colon punctuator is used primarily to delimit a
label, to describe inheritance, to indicate the
implementation of an interface, to set a generic
constraint, and as part of the conditional
operator.
• Labels are tags where program execution can be
transferred.
• A label is terminated with a colon punctuator.
• The scope of a label is limited to the containing
block and any nested block.
• Jump to a label with the goto statement.
• Label punctuator:
label_identifier: statement
• A statement must follow a label, even if it's an
empty statement.
Comma punctuator
• The comma punctuator delimits array indexes,
function parameters, types of an inheritance list,
statement clauses, and most other lists of C#
language elements.
• The comma punctuator is separating statement
clauses in the following code:
• for(int iBottom=1, iTop=10; iBottom < iTop;
++iBottom, --iTop)
• { Console.WriteLine("{0}x{1} {2}", iBottom, iTop,
iBottom*iTop); }
• A statement clause is similar to a sentence
phrase or clause, which are also sometimes
delimited by commas.
• A statement clause is a substatement in which
multiple statement clauses can be substituted
for a single statement.
• Not all statements are replaceable with
statement clauses—check the documentation
of the statement to be sure.
Comments

• C# supports four styles of comments:


– single-line,
– Delimited
– single-line documentation
– delimited documentation comments.
• Comments cannot be nested.
• Although comments are not mandated, liberal
comments are considered good programming
style.
• Self-documenting code and comments in your
source code aid in later maintenance.
• Single-line comments: // Single-line
comments start at the symbol and end at the
line terminator:
• Console.WriteLine(objGreeting.French); //
Display Hello (French)
• Delimited comments: /* and */
• Delimited comments, also called multiline or block
comments, are bracketed by the /* and */ symbols.
• Delimited comments can span multiple lines of source code:
• /* Class Program: Programmer Donis Marshall */
• class Program
• { static int Main(string[] args)
• { Greeting objGreeting = new Greeting();
• // Display Hello (French)
Console.WriteLine(objGreeting.French); return 0;
• }}
• Single-line documentation comments: ///
• Use documentation comments to apply a
consistent format to source code comments.
• Documentation comments precede types,
members, parameters, delegates, enums, and
structs; they do not precede namespaces.
• Documentation comments use XML tags to
classify comments.
• These comments are exportable to an XML file
using the documentation generator.
• The resulting file is called the documentation
file.
• Single-line documentation comments are
automated in the Visual Studio IDE.
• Visual Studio IDE has Smart Comment Editing
that inserts the comment framework after
immediately inputting the /// symbol.
• The following code snippet shows the previous
code after preceding the Main method with a
single-line documentation comment ///.
• From there, Smart Comment Editing completed
the remainder of the comment framework,
including adding comments and XML tags for the
method parameter and return.
• You only need to add specific comments.
/// <summary>
///
/// </summary>
class Program {
/// <summary>
///
/// </summary>
/// <param name="args"></param>
/// <returns></returns>

static int Main(string[] args) {


Greeting objGreeting = new Greeting();
Console.WriteLine(objGreeting.French
return 0;
}
}
• Here are the documentation comments with added details:
/// <summary>
/// Starter class for Simple HelloWorld
/// </summary>
class Program {
/// <summary>
/// Program Entry Point
/// </summary>
/// <param name="args">Command Line Parameters</param>
/// <returns>zero</returns>
static int Main(string[] args) {
Greeting objGreeting = new Greeting();
Console.WriteLine(objGreeting.French);
return 0;
}
}
• The C# compiler is a documentation generator.
• The /doc compiler option instructs the compiler to
generate the documentation file.
• Alternatively, you can request that the documentation
file be generated in the Visual Studio IDE.
• Select the Properties menu item from the Project
menu.
• From the Properties window, switch to the Build
options.
• In the Build pane (see Figure ), you can activate and
enter the name of the XML documentation file.
Delimited documentation tags
• Delimited documentation tags can be used instead of
the single-line version.
• Smart Comment Editing is not available with delimited
documentation tags.
• Documentation symbols, XML tags, and comments
must be entered manually, which is the primary
impediment to using delimited documentation tags.
• Here is an example of delimited documentation tags:
/**<summary>
Starter class for Simple HelloWorld</summary>
*/
• The documentation generator assigns IDs to
element names.
• T is the prefix for a type, whereas M is a prefix
for a method.
List of IDs
E Event
F Field
M Method
N Namespace
P Property
T Type
! Error
Preprocessor Directives

• Use preprocessor directives to define symbols,


include source code, exclude source code, name
sections of source code, and set warning and error
conditions.
• The variety of preprocessor directives is limited
when compared with C++, and many of the C++
preprocessor directives are not available in C#.
• There is not a separate preprocessor for
preprocessor statements.
• Preprocessor statements are processed by the
normal C# compiler.
Preprocessor directive:
#command expression

This is a list of preprocessor commands available in C#:


#define
#undef
#if
#else
#elif
#endif
#line
#error
#warning
#region
#endregion
#pragma
Declarative preprocessor directives
• The declarative preprocessor directives are #define and #undef,
which define and undefine a preprocessor symbol, respectively.
• Defined symbols are implicitly true, whereas undefined symbols
are false.
• Declarative symbols must be defined in each compilation unit
where the symbol is referenced.
• Undeclared symbols default to undefined and false.
• The #define and #undef directives must precede any source code.
• Redundant #define and #undef directives are trivial and have no
affect.
• Declarative preprocessor directives:
#define identifier
#undef identifier
Conditional preprocessor directives
• Conditional preprocessor directives are the #if, #else,
#elif, and #endif directives, which exclude or include
subsequent source code.
• A conditional preprocessor directives begins with #if and
ends with #endif.
• The intervening conditional preprocessing directives,
#else and #elif, are optional.
• Conditional preprocessor directives:
#if boolean_expression
#elif boolean_expression
#else
#endif
• The boolean_expression of the #if and #elif directive is a
combination of preprocessor symbols and normal
Boolean operators.
• If the boolean_expression is true, the source code
immediately after the #if or #elif directive is included in
the compilation.
• If the boolean_expression is false, the source code is
hidden.
• The #else directive can be combined with an #if or #elif
directive.
• If the boolean_expression of #if or #elif is false, the code
following the #else is included in the compilation.
• When true, the source code after the #else is hidden.
sample code with preprocess symbols and
related directives:
#define DEBUGGING

using System;

namespace Donis.CSharpBook {
class Starter{
#if DEBUGGING
static void OutputLocals() {
Console.WriteLine("debugging...");
}
#endif
static void Main() {
#if DEBUGGING
OutputLocals();
#endif
}
}
}
• Finally, the #elif directive essentially nests #if
conditional preprocessor directives:
#if expression
source_code
#elif expression
source_code
#else
source_code
#endif
Example – Consoleapplication3
• Preprocessor directives help the developer to
make programming with minimal complexity,
improving readability, ease Of maintenance,
and prompting invalid changes in the flow of
code, etc.
Diagnostic directives
• Diagnostic directives include the
– #error,
– #warning,
– #pragma directives.
• The #error and #warning directives display error
and warning messages, correspondingly.
• The diagnostic messages are displayed in the Error
List window of the Visual Studio IDE.
• Similar to standard compilation errors,
– an #error directive prevents the program from
compiling;
– a #warning directive does not prevent the program
from successfully compiling.
• Use conditional directives to conditionally apply
diagnostic directives.
• Diagnostic directives:
– #error error_message
– #warning error_message
• The error_message is of string type and is
optional.
Example – errordirective
• Example – warningdirective
• The #pragma directive enables or disables
standard compilation warnings.
• Pragma directives:
– #pragma warning disable warning_list
– #pragma warning restore warning_list
• The warning_list contains one or more warnings
delimited with commas.
• The status of a warning included in the warning_list
remains unchanged until the end of the compilation
unit unless altered in a later #error directive.
• This #pragma directive disables the 219 warning,
which is the "variable is assigned but its value is
never used" warning:
#pragma warning disable 219
class Starter{
static void Main() {
int variablea=10;
}
}
Example pragmadirective
Region directives
• Region directives mark sections of source
code.
• The #region directive starts a region, whereas
the #endregion directive ends the region.
• Region directives can be nested.
• The Visual Studio IDE outlines the source code
using region tags.
• In Visual Studio, you can collapse or expand
regions of source code.
Region directives:

#region identity
source_code
#endregion
Example regiondirective
• This directive organizes code.
• We create named "regions" of code,
terminated with endregion.
• We can then collapse these regions in Visual
Studio.
Line directives
• Line directives modify the line number reported in
subsequent compiler errors and warnings.
• There are three versions of the line directive.
– #line line_number source_filename
– #line default
– #line hidden
• The first #line directive shown renumbers the
source code from the location of the directive
until the end of the compilation unit is reached or
overridden by another #line directive.
• In the following code, the #line directive resets the
current line to 25:
#line 25
static void Main() {
Console.WriteLine("#line application");
int variablea=10; // 219 warning
}
• The second type of #line directive resets or
undoes any previous #line directive.
• The line number is reset to the natural line
number.
• The third #line directive is only tangentially
related to the line number.
• This directive does not affect the line number;
it hides source code from the debugger.
• Excluding another #line hidden directive, the
source code is hidden until the next #line
directive is encountered.
Example linedirective1
Blocks

• Blocks define the scope of a type, where type


is a class, struct, or enum.
• Additionally, members of the type are listed
inside the block.
type typename{ // block
}
• Blocks are used as compound statements.
• Paragraphs join related sentences that convey an
extended thought or concept.
• A statement block combines related statements as a
single entity.
• In this context, a statement block is a compound
statement and can contain one or more statements.
• Each statement of the statement block is delimited
by a semicolon.
• In most circumstances in which a single statement is
allowed, a statement block can be substituted.
• Statement blocks are prevalent as method bodies
but are used with conditional and iterative
statements.
• The if statement in the following code, which is a
conditional statement, controls a single statement.
• The Console.WriteLine is controlled by the if
statement that precedes it, so a statement block is
not required.

static void Main() {


int variablea=5, variableb=10;
if(((variablea*variableb)%2)==0)
Console.WriteLine("the sum is even");
}
static void Main() {
int variablea=5, variableb=10;
if(((variablea*variableb)%2)==0) {
Console.WriteLine("{0} {1}", variablea,
variableb);
Console.WriteLine("the sum is even");
}
}
Generic Types
• Generic types are templated types.
• A type is an abstraction of identity:
– a car class is an abstraction of a type of car,
– an employee class is an abstraction of an
employee,
– and a generic type is an abstraction of the
specifics of a type.
The NodeInt class partially implements and is an
abstraction of a node within a linked list of integers:

class NodeInt {
public NodeInt(int f_Value, NodeInt f_Previous) {
m_Value=f_Value;
m_Previous=f_Previous;
}

// Remaining methods

private int m_Value;


private NodeInt m_Previous;
}
The Node class is further abstracted when compared with the NodeInt class.
The integer specifics of the NodeInt class have been removed. This resulting
type could be a link list of any type:

class Node<T> {
public Node(T f_Value, Node<T> f_Previous) {

m_Value=f_Value;
m_Previous=f_Previous;
}

// Remaining methods

private T m_Value;
private Node<T> m_Previous;
}
• The generics symbol T bounds the type parameters
• discussed in detail later
Nullable Types
• Nullable types are value types that can be
assigned a null value.
• Nullable types provide a consistent
mechanism for determining whether a value
type is empty (null).
• Nullable type:
valuetype? identifier;
• discussed in detail later
Characters
• C# source files contain Unicode characters,
which are the most innate of symbols.
• Every element, keyword, operator, or identifier
in the source file is a composite of Unicode
characters.
Numeric Suffixes
• Numeric suffixes cast a literal value to a
related type.
• Literal integer values can have the
– L, U, UL, and LU suffixes appended to them;
• literal real values can have
– F, D, and M suffixes added.
• The suffixes are case insensitive.
Description of Suffixes
• Description Type Suffix
• Unsigned integer or unsigned long unit or long u
• Long or unsigned long long or ulong l
• Unsigned long ulong ul
• Float float f
• Double double d
• Money decimal m
Escape Characters
• The escape character provides an alternate means of
encoding Unicode characters, especially special characters
that are not available on a standard keyboard.
• Escape sequences can be used as characters within
identifiers and elsewhere.
• Unicode escape sequences must have four hexadecimal
digits and are therefore limited to a single character.
• Escape sequence:
\uhexadecimal digit1 digit2 digit3 digit4
• Hexadecimal escape sequences define one or more Unicode
characters and contain one or more digits.
• Hexadecimal sequence:
\xhexadecimal digit1 digit2 digitn
Predefined Escape Sequences
• Simple Escape Sequence
• Single quote \'
• Double quote \"
• Backlash \\
• Null \0
• Alert \a
• Backspace \b
• Form feed \f
• New line \n
• Carriage return \r
• Horizontal tab \t
• Unicode character \u
• Vertical tab \v
• Hexadecimal character(s) \x
Verbatim Characters
• The verbatim character prevents the translation of a
string or identifier, where it is treated "as-is."
• To create a verbatim string or identifier, prefix it with
the verbatim character.
• A verbatim string is a string literal prefixed with the
verbatim character.
• The characters of the verbatim string, including escape
sequences, are not translated.
• The exception is the quote escape character, which is
translated even in a verbatim string.
• Unlike a normal string, verbatim strings can contain
physical line feeds.
A sample verbatim string:

class Verbatim{
static void Main() {
string fileLocation=@"c:\datafile.txt";
Console.WriteLine("File is located at {0}",
fileLocation);
}
}
• A verbatim identifier is an identifier prefixed with
the verbatim character that prevents the identifier
from being parsed as a keyword.
• Although this is of limited usefulness, porting
source code from another language—in which the
keywords are different—is a circumstance in
which verbatim identifiers might be helpful.
• Otherwise, it is a best practice not to use this
language feature because verbatim identifiers
make your code less readable and harder to
maintain.
• This is a partial translation of French to English:
L'espoir is a waking dream.
• Can you decipher this sentence? Unless you are fluent in French,
the partial translation is ineffectual at best.
• The original sentence was ''L'espoir est un rêve de réveil."
• The following is an equally unskillful translation, although
technically acceptable:

public class ExampleClass {


public static void Function() {
int @for = 12;
MessageBox.Show(@for.ToString());
}
}
• In the preceding code, the for statement is
being used as a variable name.
• Although technically acceptable, it is confusing
at best.
• The for statement is common in C# and many
other programming languages.
• For this reason, most developers would view
the for as a statement regardless of the usage,
which will inevitably lead to confusion.
Operators
• Operators are used in expressions and always
return a value.
• There are three categories of operators:
– unary,
– binary,
– ternary.
• Unary operators have a single parameter.
• Prefix operators are evaluated before the
encompassing expression.
• Postfix operators are evaluated after the
encompassing expression.
Unary operators
• Operator Symbol Sample
• Unary Plus + variable=+5; 5
• Unary minus - variable=-(-10); 10
• Boolean Negation ! variable=!true; false
• Bitwise 1's complement ~ variable=~((uint)1);
• Prefix Increment ++ ++ variable; 11
• Prefix Decrement -- -- variable; 10
• Postfix Increment ++ variable ++; 11
• Postfix Decrement -- variable --; 10
• Cast Operator () variable =(int) 123.45; 123
• Function Operator ( ) FunctionCall(parameter); return value
• Array Index Operator [ ] arrayname[iIndex]; nth element
• Global Namespace Qualifier ::
Binary operators
• Binary operators have two operands:
– left operand.
– right operand.
• Integer division truncates the floating point
portion of the result.
• Bitwise Shift Left (value << bitcount).
• Bitwise Shift Right (value >> bitcount).
Binary Operators
• Operator Symbol Sample Result
• Assignment = variable=10; 10
• Binary Plus + variable=variable + 5; 15
• Binary Minus - variable=variable - 10; 5
• Multiplication * variable=variable * 5; 25
• Division / variable=variable / 5; 5
• Modulus % variable=variable % 3; 2
• Logical And & variable=5 & 3; 1
• Logical Or | variable=5 | 3; 7
• Bitwise XOR ^ variable=5 ^ 3; 6
• Bitwise Shift Left << variable=5 << 3; 40
• Bitwise Shift Right >> variable=5 >> 1; 2
• Null Coalescing ?? variableb=variablea??5 2
Compound operators
• Compound operators combine an assignment and
another operator.
• If the expanded expression is 'variablea=variablea
operator value', the compound operator is 'variable
operator= value'.
variable=variable+5;
• The preceding compound operation is equivalent to
this:
variable+=5;
• Compound operations are a shortcut and are never
required in lieu of the expanded operation.
List of Compound Operators
• Operator Symbol Sample
• Addition Assignment += variable+=5;
• Subtraction Assignment -= variable-=10;
• Multiplication Assignment *= variable*=5;
• Division Assignment /= variable/=5;
• Modulus Assignment %= variable%=3;
• And Assignment &= variable&=3;
• Or Assignment |= variable|=3;
• XOR Assignment ^= variable^= 3;
• Left-Shift Assignment <<= variable<<=3;
• Right-Shift Assignment >>= variable>>=1
Boolean operators
• Boolean expressions evaluate to true or false.
• The integer values of nonzero and zero cannot
be substituted for a Boolean true or false.
• There are two versions of the logical And and
Or operators.
• The && and || operators support
short-circuiting, whereas & and | do not.
What is short-circuiting?
• If the result of the expression can be
determined with the left side, the right side is
not evaluated.
• Without disciplined coding practices,
short-circuiting might cause unexpected side
effects.
Example

if(FunctionA() && FunctionB()) {

}
• assuming that FunctionA returns false, the
entire expression evaluates to false.
• Therefore, the expression short-circuits and
FunctionB is not invoked.
List of Boolean Operators
• Operator Symbol
• Equals ==
• Not Equal !=
• Less Than <
• Greater Than >
• And (Short Circuiting) &&
• Or (Short Circuiting) ||
• And &
• Or |
• Less Than or Equal <=
• Greater Than or Equal >=
• Logical XOR ^
Ternary operators
• The conditional operator is the sole ternary
operator in C# and is an abbreviated if else
statement.
Conditional operator:

boolean_expression?truth_statement:false_statement
• Example :
variable>5?Console.WriteLine(">5"):Console.WriteLine("<= 5");
Pointer operators
• Pointer operators are available in unsafe mode
and support conventional pointers.
• The unsafe compiler option builds a program
in unsafe mode.
• Alternatively, in Visual Studio IDE, set the
Allow Unsafe Mode option on the Build Page
of Project Settings.
List of Pointer Operators
• Operator Symbol Description
• Asterisk Operator1 * Declare a pointer
• Asterisk Operator2 * Dereference a pointer
• Ampersand Operator & Obtain an address
• Arrow Operator -> Dereference a pointer and
member access
sample code using pointers
static void Main(string[] args)
{
unsafe {
int variable = 10;
int* pVariable = &variable;
Console.WriteLine("Value at address is {0}.",
*pVariable);
}
}
• The above code must be compiled with the unsafe
compiler option on.
Identifiers

• An identifier is the name of a C# entity, which


includes type, method, property, field, and
other names.
• Identifiers can contain Unicode characters,
escape character sequences, and underscores.
• A verbatim identifier is prefixed with the
verbatim character
Keywords
• One of the strengths of C# is that the language offers
relatively few keywords.
• C# keywords represent the verbs, nouns, and adjectives
of the language.
• The nouns of C# are instances of classes, structs,
interfaces, delegates, and namespaces.
• Verbs infer an action.
• The goto, for, while, and similar keywords have that role
in C#.
• The adjectives, including the public, private, protected,
and static keywords, are modifiers of the C# nouns.

You might also like