Lập trình C# và Serial Comport Dùng vi điều khiểnFull description
Descripción: Sharp Entry
Descripción: estudio
Full description
Descripción: mmm
Full description
Service manual de l'ampli HiFi
practiceFull description
Generative Syntax across the years
C Sharp syntax
1
C Sharp syntax Main article: C Sharp (programming language) This article describes the syntax of the C# programming language. The features described are compatible with .NET Framework and Mono.
Basics Identifier An identifier is the name of an element in the code. There are certain standard naming conventions to follow when selecting names for elements. An identifier can: • start with a "_". • contain both upper case and lower case Unicode letters. Case is significant. An identifier cannot: • start with a numeral. • start with a symbol, unless it is a keyword (check Keywords). • have more than 511 chars. Keywords Keywords are predefined reserved words with special syntactic meaning. The language has two types of keyword — contextual and reserved. The reserved keywords such as false or byte may only be used as keywords. The contextual keywords such as where or from are only treated as keywords in certain situations.[1] If an identifier is needed which would be the same as a reserved keyword, it may be prefixed by the @ character to distinguish it. This facilitates reuse of .NET code written in other languages.[2] C# keywords, reserved words abstract
as
base
bool
break
by 2
byte
case
catch
char
checked
class
const
continue
decimal
default
delegate
do
double
descending 2
explicit
event
extern
else
enum
false
finally
fixed
float
for
foreach
from 2
goto
group 2
if
implicit
in
int
interface
internal
into 2
is
lock
long
new
null
namespace
object
operator
out
override
orderby 2
params
private
protected
public
C Sharp syntax
2
readonly
ref
return
switch
struct
sbyte
sealed
short
sizeof
stackalloc
static
string
select 2
this
throw
true
try
typeof
uint
ulong
unchecked
unsafe
ushort
using
var 2
virtual
volatile
void
while
where 2
yield 1
1, 2
These are not actually keywords, thus (unlike actual keywords) it is possible to define variables and types using these names, but they act like keywords in certain new language constructs introduced in C# 2.0(1) and 3.0(2).
Using a keyword as an identifier: string @out; // @out is an ordinary identifier, distinct from the 'out' keyword, //which retains its special meaning
"Hello, world" "C:\\Windows\\", @"C:\Windows\" Characters escapes in strings
Unicode character \u followed by the hexadecimal unicode code point Tab
\t
Backspace
\b
Carriage return
\r
Form feed
\f
Backslash
\\
Single quote
\'
Double quote
\"
Line feed
\n
C Sharp syntax
3
Variables Variables are identifiers associated with values. They are declared by writing the variable's type and name, and are optionally initialized in the same statement by assigning a value. Declare int MyInt; // Declaring an uninitialized variable called 'MyInt', of type 'int' Initialize int MyInt; MyInt = 35;
// Declaring an uninitialized variable // Initializing the variable
Declare & initialize int MyInt = 35; same time
// Declaring and initializing the variable at the
Multiple variables of the same type can be declared and initialized in one statement. int a, b;
// Declaring multiple variable of the same type
int a = 2, b = 3; // Declaring and initializing multiple variables of the same type Type inference This is a feature of C# 3.0. C# 3.0 introduced type inference, allowing the type specifier of a variable declaration to be replaced by the keyword var, if its actual type can be statically determined from the initializer. This reduces repetition, especially for types with multiple generic type-parameters, and adheres more closely to the DRY principle. var MyChars = new char[] {'A', 'Ö'}; // or char[] MyChars = new char[] {'A', 'Ö'}; var MyNums = new List(); See also • Type inference
// or List MyNums = new List();
C Sharp syntax
4
Constants Constants are values that are immutable and can not change. const When declaring a local variable or a field with the const keyword as a prefix the value must be given when it is declared. After that it is locked and cannot change. They can either be declared in the context as a field or a local variable. Constants are implicitly static. const double PI = 3.14; This shows all the uses of the keyword. class Foo { const double x = 3; Foo() { const int y = 2; } } readonly The readonly keyword does a similar thing to fields. Like fields marked as const they cannot change once initialized. The difference is that you can choose to initialize them in a constructor. This only works on fields. Read-only fields can either be members of an instance or static class members. class Foo { readonly int value; readonly int value2 = 3; readonly StringBuilder sb; Foo() { value = 2; sb = new StringBuilder(); } }
C Sharp syntax
5
Code blocks The operators { ... } are used to signify a code block and a new scope. Class members and the body of a method are examples of what can live inside these braces in various contexts. Inside of method bodies you can use the braces to create new scopes like so: void doSomething() { int a; { int b; a = 1; } a = 2; b = 3; //Will fail because the variable is declared in an inner scope. }
Program structure A C# application consists of classes and their members. Classes and other types exist in namespaces but can also be nested inside other classes.
Main method Whether it is a console or a graphical interface application, the program must have an entrypoint of some sort. The entrypoint of the C# application is the Main method. There can only be one, and it is a static method in a class. The method usually returns void and is passed command-line arguments as an array of strings. static void Main(string[] args) { } A Main-method is also allowed to return an integer value if specified. static int Main(string[] args) { return 0; }
Namespaces Namespaces are a part of a type name and they are used to group and/or distinguish named entities from other ones. System.IO.DirectoryInfo //DirectoryInfo is in the System.IO-namespace A namespace is defined like this: namespace FooNamespace { //Members
C Sharp syntax
6
}
using statement The using statement loads a specific namespace from a referenced assembly. It is usually placed in the top (or header) of a code file but it can be placed elsewhere if wanted, e.g. inside classes. using System; using System.Collections; You can also use the statement to define another name for an existing namespace or type. This is sometimes useful when names are too long and less readable. using Net = System.Net; using DirInfo = System.IO.DirectoryInfo;
Operators Operator category
Operators
Arithmetic
+-*/%
Logical (boolean and bitwise)
& | ^ ! ~ && ||
String concatenation
+
Increment, decrement
++ --
Shift
<< >>
Relational
== != < > <= >=
Assignment
= += -= *= /= %= &= |= ^= <<= >>=
Member access
.
Indexing
[]
Cast
()
Conditional
?:
Delegate concatenation and removal + Object creation
new
Type information
as is sizeof typeof
Overflow exception control
checked unchecked
Indirection and Address
* -> [] &
Operator overloading Some of the existing operators can be overloaded by writing an overload method. public static Foo operator+(Foo foo, Bar bar) { return new Foo(foo.Value + bar.Value); } These are the overloadable operators:
• Assignment operators (+=, *= etc.) are combinations of a binary operator and the assignment operator (=) and will be evaluated using the ordinary operators, which can be overloaded. • Cast operators (( )) cannot be overloaded, but you can define conversion operators. • Array indexing ([ ]) operator is not overloadable, but you can define new indexers. See also • Operator overloading
Conversion operators The cast operator is not overloadable but you can write a conversion operator method which lives in the target class. Conversion methods can define two varieties of operators, implicit and explicit conversion operators. The implicit operator will cast without specifying with the cast operator (( )) and the explicit operator requires it to be used. Implicit conversion operator class Foo { public int Value; public static implicit operator Foo(int value) { return new Foo(value) } } //Implicit conversion Foo foo = 2; Explicit conversion operator class Foo { public int Value; public static explicit operator Foo(int value) { return new Foo(value) } } //Explicit conversion Foo foo = (Foo)2;
C Sharp syntax as operator The as operator will attempt to do a silent cast to a given type. If it succeeds it will return the object as the new type, if it fails it will return a null reference. Stream stream = File.Open(@"C:\Temp\data.dat"); FileStream fstream = stream as FileStream; //Will return an object. String str = stream as String; //Will fail and return null.
Null coalesce operator The following return ifNotNullValue ?? otherwiseValue; Is shorthand for return ifNotNullValue != null ? ifNotNullValue : otherwiseValue; Meaning that if the content of variable ifNotNullValue is not null, that content will be returned, otherwise the content of variable otherwiseValue is returned. One can also have nullable scalar types such as int? i = null; (Both new in C Sharp 2.0.)
Control structures C# inherits most of the control structures of C/C++ and also adds new ones like the foreach statement.
Conditional structures These structures control the flow of the program through given conditions. if statement The if statement is entered when the given condition is true. Single-line case statements do not require block braces although it is mostly preferred by convention. Simple one-line statement: if (i == 3) ... ; Multi-line with else-block (without any braces): if (i == 2) ... else ... Recommended coding conventions for an if-statement. if (i == 3) { ... }
8
C Sharp syntax else if (i == 2) { ... } else { ... } switch statement The switch construct serves as a filter for different values. Each value leads to a "case". It is not allowed to fall through cases and therefore the use of the keyword break is required to end a case (the exception to this is if there is an unconditional return in a "case" block). Many cases may lead to the same code though. The default case handles all the other cases not handled by the construct. switch (ch) { case 'A': ... break; case 'B': case 'C': ... break; default: ... break; }
Iteration structures Iteration statements are statements that are repeatedly executed when a given condition is evaluated as true. while loop while (i == true) { ... } do ... while loop do { ... } while (i == true);
9
C Sharp syntax for loop The for loop consists of three parts: declaration, condition and increment. Any of them can be left out as they are optional. for (int i = 0; i < 10; i++) { ... } Is equivalent to this code represented with a while statement. { int i = 0; while (i < 10) { // ... i++; } } foreach loop The foreach statement is derived from the for statement and makes use of a certain pattern described in C#'s language specification in order to obtain and use an enumerator of elements to iterate over. Each item in the given collection will be returned and reachable in the context of the code block. When the block has been executed the next item will be returned until there are no items remaining. foreach (int i in intList) { ... }
Jump statements Jump statements are inherited from C/C++ and ultimately assembly languages through it. They simply represent the jump-instructions of an assembly language that controls the flow of a program. Labels and goto statement Labels are given points in code that can be jumped to by using the goto statement. start: ... goto start; The goto statement can be used in switch statements to jump from one case to another or to fall through from one case to the next. switch(n) { case 1: Console.WriteLine("Case 1"); break;
10
C Sharp syntax case 2: Console.WriteLine("Case 2"); goto case 1; case 3: Console.WriteLine("Case 3"); case 4: // Compilation will fail here as cases cannot fall through in C#. Console.WriteLine("Case 4"); goto default; // This is the correct way to fall through to the next case. default: Console.WriteLine("Default"); } break statement The break statement breaks out of the closest loop or switch statement. Execution continues in the statement after the terminated statement, if any. int e = 10; for (int i=0; i < e; i++) { while (true) { break; } // Will break to this point. } continue statement The continue statement discontinues the current iteration of the current control statement and begins the next iteration. int ch; while ((ch = GetChar()) >= 0) { if (ch == ' ') continue; // Skips the rest of the while-loop // Rest of the while-loop ... } The while loop in the code above reads characters by calling GetChar(), skipping the statements in the body of the loop if the characters are spaces.
11
C Sharp syntax
Exception handling C# has a neat way of handling runtime exceptions that is inherited from Java and C/C++ through it. The base class library has a class called System.Exception from which all exceptions are derived. An Exception-object contains all the information about a specific exception and also the inner exceptions that were caused. The programmer may define their own exceptions by deriving from the Exception class. An exception can be thrown this way: throw new NotImplementedException(); try ... catch ... finally statements Exceptions are managed within try ... catch blocks. try { // Statements which may throw exceptions ... } catch (Exception ex) { // Exception caught and handled here ... } finally { // Statements always executed after the try/catch blocks ... } The statements within the try block are executed, and if any of them throws an exception, execution of the block is discontinued and the exception is handled by the catch block. There may be multiple catch blocks, in which case the first block with an exception variable whose type matches the type of the thrown exception is executed. If no catch block matches the type of the thrown exception, the execution of the outer block (or method) containing the try ... catch statement is discontinued, and the exception is passed up and outside the containing block (or method). The exception is propagated upwards through the call stack until a matching catch block is found within one of the currently active methods. If the exception propagates all the way up to the top-most Main() method without a matching catch block being found, the entire program is terminated and a textual description of the exception is written to the standard output stream. The statements within the finally block are always executed after the try and catch blocks, whether or not an exception was thrown. Such blocks are useful for providing clean-up code that is guaranteed to always be executed. The catch and finally blocks are optional, but at least one or the other must be present following the try block.
12
C Sharp syntax
13
Types C# is a statically-typed language like C and C++. That means that every variable and constant get a fixed type when they are being declared. There are two kinds of types: value types and reference types.
Value types Instances of value types reside on the stack, i.e. they are bound to their variables. If you declare a variable for a value type the memory gets allocated directly. If the variable gets out of scope the object is destroyed with it. Structures Structures are more commonly known as structs. Structs are user-defined value types that are declared using the struct keyword. They are very similar to classes but are more suitable for lightweight types. Some important syntactical differences between a class and a struct are presented later in this article. struct Foo { ... } The primitive data types are all structs. Pre-defined types These are the primitive datatypes. Primitive Types Type Name
BCL Equivalent
Value
Range
sbyte
System.SByte
integer
−128 through +127
8-bit (1-byte)
0
short
System.Int16
integer
−32,768 through +32,767
16-bit (2-byte)
0
int
System.Int32
integer
−2,147,483,648 through +2,147,483,647
32-bit (4-byte)
0
long
System.Int64
integer
−9,223,372,036,854,775,808 through +9,223,372,036,854,775,807
64-bit (8-byte)
0
byte
System.Byte
unsigned integer
0 through 255
8-bit (1-byte)
0
ushort
System.UInt16
unsigned integer
0 through 65,535
16-bit (2-byte)
0
uint
System.UInt32
unsigned integer
0 through 4,294,967,295
32-bit (4-byte)
0
ulong
System.UInt64
unsigned integer
0 through 18,446,744,073,709,551,615
64-bit (8-byte)
0
decimal
System.Decimal
signed decimal number
−7.9228162514264337593543950335 through +7.9228162514264337593543950335
128-bit (16-byte) 0.0
float
System.Single
floating point number
±1.401298E−45 through ±3.402823E+38
32-bit (4-byte)
0.0
double
System.Double
floating point number
±4.94065645841246E−324 through ±1.79769313486232E+308
64-bit (8-byte)
0.0
bool
System.Boolean
Boolean
true or false
8-bit (1-byte)
false
char
System.Char
single Unicode character '\u0000' through '\uFFFF'
16-bit (2-byte)
'\u0000'
Note: string (System.String) is not a struct and is not a primitive type.
Size
Default Value
C Sharp syntax
14
Enumerations Enumerated types (enums) are named values representing integer values. enum Season { Winter = 0, Spring = 1, Summer = 2, Autumn = 3, Fall = Autumn }
//Autumn is called Fall in American English.
enum instances are declared as ordinary variables and are initialized by default to zero. They can be assigned or initialized to the named values defined by the enumeration type. Season season; season = Season.Spring;
enum types variables are basically integer values. That means that addition and subtraction between variables of the same type is allowed without any specific cast but multiplication and division is somewhat more risky and requires it explicitly. Casts are also required to and from integer types. It will however throw an exception if the value is not allowed. season = (Season)2; //2 to an enum-value of type Season. season = season + 1; //Adds 1 to the value. season = season + season2; //Adding the values of two variables. int value = (int)season; //Casting enum-value to integer value. season++; //Season.Spring (1) becomes Season.Summer (2). season--; //Season.Summer (2) becomes Season.Spring (1). Values can be combined using the bitwise-OR operator, |. Color myColors = Color.Green | Color.Yellow | Color.Blue;
See also • Enumeration (programming)
Reference types Variables created for reference types are typed managed references. When the constructor is called an object is created on the heap and a reference is assigned to the variable. When a variable of an object gets out of scope the reference is broken and when there are no references left the object gets marked as garbage. The garbage collector will then soon collect and destroy it. A reference variable is null when it does not reference any object.
C Sharp syntax Arrays An array type is a reference type that refers to a space containing one or more elements of a certain type. All array types derive from a common base class, System.Array. Each element is referenced by its index just like in C++ and Java. An array in C# is what would be called a dynamic array in C++. int[] numbers = new int[5]; numbers[0] = 2; numbers[1] = 5; int x = numbers[0]; Initializers Array initializers provide convenient syntax for initialization of arrays. //Long syntax int[] numbers = new int[5]{ 20, 1, 42, 15, 34 }; //Short syntax int[] numbers2 = { 20, 1, 42, 15, 34 }; Multi-dimensional arrays Arrays can have more than one dimension, for example 2 dimensions to represent a grid. int[,] numbers = new int[3, 3]; numbers[1,2] = 2; int[,] numbers2 = new int[3, 3] { {2, 3, 2}, {1, 2, 6}, {2, 4, 5} }; See also • Jagged array Classes Classes are self-describing user-defined reference types. Essentially all types in the .NET Framework are classes, including structs and enums, that are compiler generated classes. String class The System.String class, or simply string, represents an immutable sequence of unicode characters (char). Actions performed on a string will always return a new string. string text = "Hello World!"; string substr = text.Substring(0, 5); string[] parts = text.Split(new char[]{ ' ' }); The System.StringBuilder class can be used when a mutable "string" is wanted. StringBuilder sb = new StringBuilder(); sb.Append('H'); sb.Append("el"); sb.AppendLine("lo!");
15
C Sharp syntax
16
Interface Interfaces are data structures that contain member definitions with no actual implementation. They are useful for when you want to define a contract between members in different types that have different implementations. You can declare definitions for methods, properties, and indexers. These must be implemented by a class as public members. interface IBinaryOperation { double A { get; set; } double B { get; set; } double GetResult(double a, double b); } Delegates C# provides type-safe object-oriented function pointers in the form of delegates. class Program { //Delegate type . delegate int Operation(int a, int b); static int Add(int i1, int i2) { return i1 + i2; } static int Sub(int i1, int i2) { return i1 - i2; } static void Main() { //Instantiate the delegate and assign the method to it. Operation op = Add; //Call the method that the delegate points to. int result1 = op(2, 3); //5 op = Sub; int result2 = op(10, 2); //8 } } Initializing the delegate with an anonymous method. addition = delegate(int a, int b){ return a + b; }; See also
C Sharp syntax
17
• Delegate (.NET) Events Events are pointers that can point to multiple methods. More exactly they bind method pointers to one identifier. This can therefore be seen as an extension to delegates. They are typically used as triggers in UI development. The form used in C# and the rest of the Common Language Infrastructure is based on that in the classic Visual Basic. delegate void MouseEventHandler(object sender, MouseEventArgs e); public class Button : System.Windows.Controls.Control { event MouseEventHandler OnClick; /* Imaginary trigger function */ void click() { this.OnClick(this, new MouseEventArgs(data)); } } An event requires an accompanied event handler that is made from a special delegate that in a platform specific library like in Windows Presentation Foundation and Windows Forms usually takes two parameters: sender and the event arguments. The type of the event argument-object derive from the EventArgs class that is a part of the CLI base library. Once declared in its class the only way of invoking the event is from inside of the owner. A listener method may be implemented outside to be triggered when the event is fired. public class MainWindow : System.Windows.Controls.Window { private Button button1; public MainWindow() { button1 = new Button(); button1.Text = "Click me!"; /* Subscribe to the event */ button1.ClickEvent += button1_OnClick; /* Alternate syntax that is considered old: button1.MouseClick += new MouseEventHandler(button1_OnClick); */ } protected void button1_OnClick(object sender, MouseEventArgs e) { MessageBox.Show("Clicked!"); } }
C Sharp syntax
18
See also • Event-driven programming Nullable types This is a feature of C Sharp 2.0. Nullable types were introduced in C Sharp 2.0 firstly to enable value types to be null when working with a database. int? n = 2; n = null; Console.WriteLine(n.HasValue); In reality this is the same as using the Nullable struct. Nullable n = 2; n = null; Console.WriteLine(n.HasValue); Pointers C# has and allows pointers to value types (primitives, enums and structs) in unsafe context: methods and codeblock marked unsafe. These are syntactically the same as pointers in C and C++. However, runtime-checking is disabled inside unsafe blocks. static void Main(string[] args) { unsafe { int a = 2; int* b = &a; Console.WriteLine("Address of a: {0}. Value: {1}", (int)&a, a); Console.WriteLine("Address of b: {0}. Value: {1}. Value of *b: {2}", (int)&b, (int)b, *b); //Will output something like: //Address of a: 71953600. Value: 2 //Address of b: 71953596. Value: 71953600.
Value of *b: 2
} } Structs are required only to be pure structs with no members of a managed reference type, e.g. a string or any other class. public struct MyStruct { public char Character; public int Integer; }
C Sharp syntax
19
public struct MyContainerStruct { public byte Byte; public MyStruct MyStruct; } In use: MyContainerStruct x; MyContainerStruct* ptr = &x; byte value = ptr->Byte; See also • Pointer (programming) Dynamic This is a feature of C Sharp 4.0 and .NET Framework 4.0. Type dynamic is a feature that enables dynamic runtime lookup to C# in a static manner. Dynamic is a static "type" which exists at runtime. dynamic x = new Foo(); x.DoSomething(); //Will compile and resolved at runtime. An exception will be thrown if invalid.
Boxing and unboxing Boxing is the operation of converting a value of a value type into a value of a corresponding reference type.[3] Boxing in C# is implicit. Unboxing is the operation of converting a value of a reference type (previously boxed) into a value of a value type.[3] Unboxing in C# requires an explicit type cast. Example: int foo = 42; object bar = foo; int foo2 = (int)bar;
// Value type. // foo is boxed to bar. // Unboxed back to value type.
Object-oriented programming (OOP) C# has direct support for object-oriented programming.
Objects An object is created with the type as a template and is called an instance of that particular type. In C# objects are either references or values. No further syntactical distinction is made between those in code. object class All types, even value types in their boxed form, implicitly inherit from the System.Object class which is the ultimate base class of all objects. The class contains the most common methods shared by all objects. Some of these are virtual and can be overridden. Classes inherit System.Object either directly or indirectly through another base class.
C Sharp syntax
20
Members Some of the members of the Object class: • Equals - Supports comparisons between objects. • Finalize - Performs cleanup operations before an object is automatically reclaimed. (Default destructor) • GetHashCode - Gets the number corresponding to the value of the object to support the use of a hash table. • GetType - Gets the Type of the current instance. • ToString - Creates a human-readable text string that describes an instance of the class. Usually it returns the name of the type.
Classes Classes are fundamentals of an object-oriented language such as C#. They serve as a template for objects. They contain members that store and manipulate data in a real-life-like way. See also • Class (computer science) • Structure (computer science) Differences between classes and structs Although classes and structures are similar in both the way they are declared and how they are used, there are some significant differences. Classes are reference types and structs value types. A structure is allocated on the stack when it is declared and the variable is bound to its address. It directly contains the value. Classes are different because the memory is allocated as objects on the heap. Variables are rather managed pointers on the stack which point to the objects. They are references. Structures require some more than classes. For example, you need to explicitly create a default constructor which takes no arguments to initialize the struct and its members. The compiler will create a default one for classes. All fields and properties of a struct must have been initialized before an instance is created. Structs do not have finalizers and cannot inherit from another class like classes do. However, they inherit from System.ValueType, that inherits from System.Object. Structs are more suitable for smaller constructs of data. This is a short summary of the differences: Default constructor
Finalizer
Member initialization
Inheritance
Classes
not required (auto generated) yes
not required
yes (if base class is not sealed)
Structs
required (not auto generated) no
required
not supported
Declaration A class is declared like this: class Foo { //Member declarations }
C Sharp syntax Partial class This is a feature of C Sharp 2.0. A partial class is a class declaration whose code is divided into separate files. The different parts of a partial class must be marked with keyword partial. //File1.cs partial class Foo { ... } //File2.cs partial class Foo { ... } Initialization Before you can use the members of the class you need to initialize the variable with a reference to an object. To create it you call the appropriate constructor using the new keyword. It has the same name as the class. Foo foo = new Foo(); For structs it is optional to explicitly call a constructor because the default one is called automatically. You just need to declare it and it gets initialized with standard values. Object initializers This is a feature of C Sharp 3.0. Provides a more convenient way of initializing public fields and properties of an object. Constructor calls are optional when there is a default constructor. Person person = new Person { Name = "John Doe", Age = 39 }; //Equal to Person person = new Person(); person.Name = "John Doe"; person.Age = 39;
21
C Sharp syntax Collection initializers This is a feature of C Sharp 3.0. Collection initializers give an array-like syntax for initializing collections. The compiler will simply generate calls to the Add-method. This works for classes that implement the interface ICollection. List list = new List {2, 5, 6, 6 }; //Equal to List list = new List(); list.Add(2); list.Add(5); list.Add(6); list.Add(6); Accessing members Members of both instances and static classes are accessed with the . operator. Accessing an instance member Instance members can be accessed through the name of a variable. string foo = "Hello"; string fooUpper = foo.ToUpper(); Accessing a static class member Static members are accessed by using the name of the class or any other type. int r = String.Compare(foo, fooUpper); Accessing a member through a pointer In unsafe code, members of a value (struct type) referenced by a pointer are accessed with the -> operator just like in C and C++. POINT p; p.X = 2; p.Y = 6; POINT* ptr = &p; ptr->Y = 4; Modifiers Modifiers are keywords used to modify declarations of types and type members. Most notably there is a sub-group containing the access modifiers. • • • • •
abstract - Specifies that a class only serves as a base class. It must be implemented in an inheriting class. const - Specifies that a variable is a constant value that has to be initialized when it gets declared. event - Declare an event. extern - Specify that a method signature without a body uses a DLL-import. override - Specify that a method or property declaration is an override of a virtual member or an implementation of a member of an abstract class.
• readonly - Declare a field that can only be assigned values as part of the declaration or in a constructor in the same class. • sealed - Specifies that a class cannot be inherited. • static - Specifies that a member belongs to the class and not to a specific instance. (see section static)
22
C Sharp syntax
23
• unsafe - Specifies an unsafe context, which allows the use of pointers. • virtual - Specifies that a method or property declaration can be overridden by a derived class. • volatile - Specifies a field which may be modified by an external process and prevents an optimizing compiler from modifying the use of the field. Access modifiers The access modifiers, or inheritance modifiers, set the accessibility of classes, methods, and other members. Something marked public can be reached from anywhere. private members can only be accessed from inside of the class they are declared in and will be hidden when inherited. Members with the protected modifier will be private, but accessible when inherited. internal classes and members will only be accessible from the inside of the declaring assembly. Classes and structs are implicitly internal and members are implicitly private if they do not have an access modifier. public class Foo { public int Do() { return 0; } public class Bar { } } Unnested types
Members (incl. Nested types)
public
yes
yes
private
no
yes (default)
protected
no
yes
yes (default)
yes
internal
protected internal no
yes
static The static modifier states that a member belongs to the class and not to a specific object. Classes marked static are only allowed to contain static members. Static members are sometimes referred to as class members since they apply to the class as a whole and not to its instances. public class Foo { public static void Something() { ... } } //Calling the class method. Foo.Something();
C Sharp syntax Constructors A constructor is a special method that is called when an object is going to be initialized. Its purpose is to initialize the members of the object. The main differences between constructors and ordinary methods are that constructors are named after the class and do not return anything. They may take parameters as any method. class Foo { Foo() { ... } } Constructors can be public, private, or internal. See also • Constructor (computer science) Destructor The destructor is called when the object is being collected by the garbage collector to perform some manual clean-up. There is a default destructor method called finalize that can be overridden by declaring your own. The syntax is similar to the one of constructors. The difference is that the name is preceded by a ~ and it cannot contain any parameters. There cannot be more than one destructor. class Foo { ... ~Foo() { ... } } Finalizers are always private. See also • Destructor (computer science) Methods Like in C and C++ there are functions that group reusable code. The main difference is that functions just like in Java have to reside inside of a class. A function is therefore called a method. A method has a return value, a name and usually some parameters initialized when it is called with some arguments. It can either belong to an instance of a class or be a static member. class Foo { int Bar(int a, int b) { return a % b; }
24
C Sharp syntax } A method is called using . notation on a specific variable, or as in the case of static methods, the name of a type. Foo foo = new Foo(); int r = foo.Bar(7, 2) Console.WriteLine(r); See also • Method (computer science) ref and out parameters One can explicitly make arguments be passed by reference when calling a method with parameters preceded by keywords ref or out. These managed pointers come in handy when passing value type variables that you want to be modified inside the method by reference. The main difference between the two is that an out parameter must have been assigned within the method by the time the method returns, while ref need not assign a value. void PassRef(ref int x) { if(x == 2) x = 10; } int Z; PassRef(ref Z); void PassOut(out int x) { x = 2; } int Q; PassOut(out Q); Optional parameters This is a feature of C Sharp 4.0. C# 4.0 introduces optional parameters with default values as seen in C++. For example: void Increment(ref int x, int dx = 1) { x += dx; } int x = 0; Increment(ref x); // dx takes the default value of 1 Increment(ref x, 2); // dx takes the value 2 In addition, to complement optional parameters, it is possible to explicitly specify parameter names in method calls, allowing to selectively pass any given subset of optional parameters for a method. The only restriction is that named parameters must be placed after the unnamed parameters. Parameter names can be specified for both optional and required parameters, and can be used to improve readability or arbitrarily reorder arguments in a call. For example:
25
C Sharp syntax
26
Stream OpenFile(string name, FileMode mode = FileMode.Open, FileAccess access = FileAccess.Read) { ... } OpenFile("file.txt"); // use default values for both "mode" and "access" OpenFile("file.txt", mode: FileMode.Create); // use default value for "access" OpenFile("file.txt", access: FileAccess.Read); // use default value for "mode" OpenFile(name: "file.txt", access: FileAccess.Read, mode: FileMode.Create); // name all parameters for extra readability, // and use order different from method declaration Optional parameters make interoperating with COM easier. Previously, C# had to pass in every parameter in the method of the COM component, even those that are optional. For example: object fileName = "Test.docx"; object missing = System.Reflection.Missing.Value; doc.SaveAs(ref fileName, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, console.writeline("File saved
With support for optional parameters, the code can be shortened as doc.SaveAs(ref fileName); extern A feature of C# is the ability to call native code. A method signature is simply declared without a body and is marked as extern. The DllImport attribute also needs to be added to reference the desired DLL file. [DllImport("win32.dll")] static extern double Pow(double a, double b); Fields Fields, or class variables, can be declared inside the class body to store data. It is considered good practice to keep a field private and declare a property to access it. class Foo { double foo; } Fields can be initialized directly when declared.
C Sharp syntax class Foo { double foo = 2.3; } Modifiers for fields: • • • • • •
static - Makes the field a static member. readonly - Allows the field to be initialized only once in a constructor. const - Makes the field a constant. public - Makes the field public. private - Makes the field private (default). protected - Makes the field protected.
Properties Properties bring field-like syntax and combine them with the power of methods. A property can have two accessors: get and set. class Person { string name; string Name { get { return name; } set { name = value; } } } //Using a property Person person = new Person(); person.Name = "Robert"; Modifiers for properties: • static - Makes the property a static member. • public - Makes the property public. • private - Makes the property private (default). • protected - Makes the property protected. Modifiers for property accessors: • public - Makes the accessor public. • private - Makes the accessor private. • protected - Makes the accessor protected. The default modifiers for the accessors are inherited from the property. Note that the accessor's modifiers can only be equal or more restrictive than the property's modifier.
27
C Sharp syntax Automatic properties This is a feature of C Sharp 3.0. A feature of C# 3.0 is auto-implemented properties. You define accessors without bodies and the compiler will generate a backing field and the necessary code for the accessors. double Width { get; private set; } Indexers Indexers add array-like indexing capabilities to objects. They are implemented in a way similar to properties. class IntList { int[] items; int this[int index] { get { return this.items[index]; } set { this.items[index] = value; } } } //Using an indexer IntList list = new IntList(); list[2] = 2; Inheritance Classes in C# may only inherit from one class. A class may derive from any class that is not marked as sealed. class A { } class B : A { } See also • Inheritance (computer science)
28
C Sharp syntax virtual Methods marked virtual provide an implementation, but they can be overridden by the inheritors by using the override keyword. The implementation is chosen by the actual type of the object and not the type of the variable. class Operation { public virtual int Do() { return 0; } } class NewOperation : Operation { public override int Do() { return 1; } } new When overloading a non-virtual method with another signature, the keyword new may be used. The used method will be chosen by the type of the variable instead of the actual type of the object. class Operation { public int Do() { return 0; } } class NewOperation : Operation { public new double Do() { return 4.0; } } This demonstrates the case: NewOperation operation = new NewOperation; // Will call "double Do()" in NewOperation double d = operation.Do(); Operation operation_ = operation;
29
C Sharp syntax
// Will call "int Do()" in Operation int i = operation_.Do(); abstract Abstract classes are classes that only serve as templates and you can not initialize an object of that type. Otherwise it is just like an ordinary class. There may be abstract members too. Abstract members are members of abstract classes that do not have any implementation. They must be overridden by the class that inherits the member. abstract class Mammal { public abstract void Walk(); } class Human : Mammal { public override void Walk() { } ... } sealed The sealed modifier can be combined with the others as an optional modifier for classes to make them uninheritable. internal sealed class _FOO { }
Interfaces Interfaces are data structures that contain member definitions and not actual implementation. They are useful when you want to define a contract between members in different types that have different implementations. You can declare definitions for methods, properties, and indexers. An interface can either be implicitly or explicitly implemented. interface IBinaryOperation { double A { get; set; } double B { get; set; } double GetResult(double a, double b); }
30
C Sharp syntax Implementing an interface An interface is implemented by a class or extended by another interface in the same way you derive a class from another class using the : notation. Implicit implementation When implicitly implementing an interface the members of the interface have to be public. public class Adder : IBinaryOperation { public double A { get; set; } public double B { get; set; } public double GetResult() { return A + B; } } public class Multiplier : IBinaryOperation { public double A { get; set; } public double B { get; set; } public double GetResult() { return A * B; } } In use: IBinaryOperation op = null; double result; // Adder implements the interface IBinaryOperation. op = new Adder(); op.A = 2; op.B = 3; result = op.GetResult(); //5
// Multiplier also implements the interface. op = new Multiplier(); op.A = 5; op.B = 4;
31
C Sharp syntax result = op.GetResult(); //20 Explicit implementation You can also explicitly implement members. The members of the interface that are explicitly implemented by a class are accessible only when the object is handled as the interface type. public class Adder : IBinaryOperation { double IBinaryOperation.A { get; set; } double IBinaryOperation.B { get; set; } double IBinaryOperation.GetResult() { return A + B; } } In use: Adder add = new Adder(); // These members are not accessible. // add.A = 2; // add.B = 3; // double result = add.GetResult(); //Cast to the interface type to access them. IBinaryOperation add2 = add; add2.A = 2; add2.B = 3; double result = add2.GetResult(); Note: The properties in the class that extends IBinaryOperation are auto-implemented by the compiler. Both get a backingfield. Extending multiple interfaces Interfaces and classes are allowed to extend multiple interfaces. class MyClass : IInterfaceA, IInterfaceB { ... } Here is a interface that extends two interfaces. interface IInterfaceC : IInterfaceA, IInterfaceB { ...
32
C Sharp syntax } Interfaces vs . Abstract classes Interfaces and abstract classes are similar. The following describes some important differences: • • • • •
An abstract class may have member variables as well as non-abstract methods or properties. An interface cannot. A class or abstract class can only inherit from one class or abstract class. A class or abstract class may implement one or more interfaces. An interface can only extend other interfaces. An abstract class may have non-public methods and properties (also abstract ones). An interface can only have public members. • An abstract class may have constants, static methods and static members. An interface cannot. • An abstract class may have constructors. An interface cannot.
Generics This is a feature of C Sharp 2.0 and .NET Framework 2.0. Generics, or parameterized types, or parametric polymorphism is a .NET 2.0 feature supported by C#. Unlike C++ templates, .NET parameterized types are instantiated at runtime rather than by the compiler; hence they can be cross-language whereas C++ templates cannot. They support some features not supported directly by C++ templates such as type constraints on generic parameters by use of interfaces. On the other hand, C# does not support non-type generic parameters. Unlike generics in Java, .NET generics use reification to make parameterized types first-class objects in the Common Language Infrastructure (CLI) Virtual Machine, which allows for optimizations and preservation of the type information.[4] See also • Generic programming
Using Generics Generic classes Classes and structs can be generic. public class List { ... public void Add(T item) { ... } } List list = new List(); list.Add(6); list.Add(2);
33
C Sharp syntax Generic interfaces interface IEnumerable { ... } Generic delegates delegate R Func(T1 a1, T2 a2); Generic methods public static T[] CombineArrays(T[] a, T[] b) { T[] newArray = new T[a.Length + b.Length]; a.CopyTo(newArray, 0); b.CopyTo(newArray, a.Length); return newArray; } string[] a = new string[] { "a", "b", "c" }; string[] b = new string[] { "1", "2", "3" }; string[] c = CombineArrays(a, b); double[] da = new double[] { 1.2, 2.17, 3.141592 }; double[] db = new double[] { 4.44, 5.6, 6.02 }; double[] dc = CombineArrays(da, db); //c is a string array containing { "a", "b", "c", "1", "2", "3"} //dc is a double array containing { 1.2, 2.17, 3.141592, 4.44, 5.6, 6.02}
Type-parameters Type-parameters are names used in place of concrete types when defining a new generic. They may be associated with classes or methods by placing the type parameter in angle brackets < >. When instantiating (or calling) a generic, you can then substitute a concrete type for the type-parameter you gave in its declaration. Type parameters may be constrained by use of the where keyword and a constraint specification, any of the six comma separated constraints may be used:
34
C Sharp syntax
35
Constraint
Explanation
where T : struct
type parameter must be a value type
where T : class
type parameter must be a reference type
where T : new()
type parameter must have a constructor with no parameters (must appear last)
where T : type parameter must inherit from where T :
type parameter must be, or must implement this interface
where T : U
naked type parameter constraint
Covariance and contravariance This is a feature of C Sharp 4.0 and .NET Framework 4.0. Generic interfaces and delegates can have their type parameters marked as covariant or contravariant, using keywords out and in, respectively. These declarations are then respected for type conversions, both implicit and explicit, and both compile-time and run-time. For example, the existing interface IEnumerable has been redefined as follows: interface IEnumerable { IEnumerator GetEnumerator(); } Therefore, any class that implements IEnumerable for some class Derived is also considered to be compatible with IEnumerable for all classes and interfaces Base that Derived extends, directly, or indirectly. In practice, it makes it possible to write code such as: void PrintAll(IEnumerable