Use LEFT and RIGHT arrow keys to navigate between flashcards;
Use UP and DOWN arrow keys to flip the card;
H to show hint;
A reads text to speech;
145 Cards in this Set
- Front
- Back
chief architect of the language |
Anders Hejlsberg |
|
Unified type system |
The fundamental building block in C# is an encapsulated unit of data and functions called a type. C# has a unified type system, where all types ultimately share a common base type. This means that all types, whether they represent business objects or are primitive types such as numbers, share the same basic |
|
Interface in C# |
An interface is like a class, except that it only describes members. The implementation for |
|
Properties, methods, and events |
In C#, methods are only one kind of function member, which also includes properties and events (there are others, too). Properties are function members that encapsulate a piece of an object’s state, such as a button’s color or a label’s text. Events are function members that simplify acting on object state changes. |
|
C# is primarily a type-safe language, meaning |
C# is primarily a type-safe language, meaning that instances of types can interact only through protocols they define, thereby ensuring each type’s internal consistency.
|
|
static typing |
meaning that the language enforces type safety at compile time. |
|
C# is also called a strongly typed language because |
its type rules (whether enforced statically or at runtime) are very strict. For instance, you cannot call a function that’s designed to accept an integer with a floating-point number, unless you first explicitly convert the floating-point number to an integer. This helps prevent mistakes |
|
C# code may run on a runtime other than the Microsoft Common Language Runtime. The most notable example is the |
Mono project, which has its own |
|
.NET Framework consists of
WinRT |
.NET Framework consists of CLR plus a vast set of libraries.
WinRT - Windows Runtime |
|
WinRT |
WinRT is an execution interface and runtime environment for accessing libraries in a languageneutral and object-oriented fashion. It ships with Windows 8 and is (in part) an enhanced version of Microsoft’s Component Object Model or COM |
|
reference assembly |
exists purely to compile against and may |
|
C# 5.0’s big new feature is |
support for asynchronous functions via two new keywords, async and await. Asynchronous functions enable asynchronous continuations, |
|
What’s New in C# 4.0 |
• Dynamic binding |
|
Dynamic binding |
Dynamic binding defers binding—the process of resolving types and members—from compile time to runtime and is useful in scenarios that would otherwise require complicated reflection code. Dynamic binding is also useful when interoperating with dynamic languages and COM components. |
|
Optional parameters |
Optional parameters allow functions to specify default parameter values so that callers can omit arguments and named arguments allow a function caller to identify an argument by name rather than position. |
|
Type variance |
Type variance rules were relaxed in C# 4.0 4), such that type parameters in generic interfaces and generic delegates can be marked as covariant or contravariant, allowing more natural type conversions |
|
COM interoperability |
COM interoperability was enhanced in C# 4.0 in three ways First, arguments can be passed by reference without the ref keyword (particularly useful
Second, assemblies that contain COM
Third, functions that return COM-Variant |
|
Implicitly typed local variables |
let you omit the variable type in a declaration statement, allowing the compiler to infer it. This reduces clutter as well as allowing anonymous types 4), which are simple classes created on the fly that are commonly used in the final output of LINQ queries. Arrays can also be implicitly typed |
|
Object initializers |
simplify object construction by allowing properties to be set inline after the constructor call. Object initializers work with both named and anonymous types.
public class Bunny {
Bunny b1 = new Bunny { Name="Bo", LikesCarrots=true, LikesHumans=false }; |
|
Lambda expressions |
are miniature functions created by the compiler on the fly, and are particularly useful in “fluent” LINQ queries |
|
Extension methods |
Extension methods extend an existing type with new methods (without altering the type’s definition), making static methods feel like instance methods. LINQ’s query operators are implemented as extension methods. |
|
Query expressions |
provide a higher-level syntax for writing LINQ queries that can be substantially simpler when working with multiple sequences or range |
|
Expression trees |
are miniature code DOMs (Document Object Models) that describe lambda expressions assigned to the special type Expressiongate>. Expression trees make it possible for LINQ queries to execute remotely because they can be introspected and translated at runtime |
|
Automatic properties |
Automatic properties cut the work in writing properties that simply get/set a private backing field by having the compiler do that work automatically |
|
Partial `methods |
Partial methods let an auto-generated partial class provide customizable hooks for manual authoring which “melt away” if unused.
partial class PaymentForm // In auto-generated file { |
|
C# compiler compiles source code |
C# compiler compiles source code, specified as a set of files with the .cs extension, into an assembly. An assembly is the unit of packaging and deployment in .NET. An assembly can be either an application or a library. A normal console or Windows application has a Main method and is an .exe file. A library is a .dll and is equivalent to an .exe without an entry point. Its purpose is to be called upon (referenced) |
|
If you really want to use an identifier that clashes with a keyword, you can do so by qualifying it with |
the @ prefix. For instance:
The @ symbol doesn’t form part of the identifier itself. So @myVariable is the same as dmyVariable. |
|
Data members and function members that don’t operate on the instance of the type, but rather on the type itself, must be marked as |
static. The Test.Main and Console.WriteLine methods are static methods. |
|
Implicit conversions are allowed when both of the following are true |
The compiler can guarantee they will always succeed. |
|
explicit conversions are required when one of the following is true |
The compiler cannot guarantee they will always succeed. |
|
All C# types fall into the following categories |
Value types - most built in type Reference types |
|
checked operator |
checked operator tells the runtime to generate an OverflowException rather than overflowing silently when an integral expression or statement exceeds the arithmetic limits of that type.
int a = 1000000; |
|
unchecked operator |
If you then need to disable overflow checking just for specific expressions or statements, you can do so with the unchecked operator. For example, the following code will not throw exceptions—even if compiled with /checked+: |
|
short x = 1, y = 1; |
In this case, x and y are implicitly converted to int so that the addition can be performed. This means the result is also an int, which cannot be implicitly cast back to a short (because it could cause loss of data)
The 8- and 16-bit integral types are byte, sbyte, short, and ushort. These types lack their own arithmetic operators, so C# implicitly converts them to larger types as required. |
|
Special Float and Double Values |
Unlike integral types, floating-point types have values that certain operations treat specially. These special values are NaN (Not a Number), +∞, −∞, and −0. |
|
Dividing a nonzero number by zero results in an infinite value. For example: Console.WriteLine ( 1.0 / 0.0); // ? Console.WriteLine ( -1.0 / 0.0); // ? Console.WriteLine ( 1.0 / -0.0); // ? Console.WriteLine ( -1.0 / -0.0); // ? |
Console.WriteLine ( 1.0 / 0.0); // Infinity |
|
Dividing zero by zero, or subtracting infinity from infinity, results in a NaN. For example:
Console.WriteLine ( 0.0 / 0.0); //?? Console.WriteLine ((1.0 / 0.0) − (1.0 / 0.0)); // ?? |
Console.WriteLine ( 0.0 / 0.0); // NaN |
|
When using ==, a NaN value is _______________ ? |
When using ==, a NaN value is never equal to another value, even another NaN value: |
|
When using object.Equals two NaN values are ___________ |
equal: |
|
double Versus decimal |
double is useful for scientific computations (such as computing spatial coordinates). decimal is useful for financial computations and values that are “man-made” rather than the result of real-world measurements. |
|
conditional operator def |
q ? a : b
static int Max (int a, int b)
|
|
Arrays |
char[] vowels = new char[5]; // Declare an array of 5 characters |
|
array initialization expression |
array initialization expression lets you declare and populate an array in a single step:
char[] vowels = new char[] {'a','e','i','o','u'};
or simply: |
|
Multidimensional arrays come in two varieties |
rectangular - int[,] matrix = new int[3,3]; jagged - int[][] matrix = new int[3][]; // for jagged array for (int i = 0; i < matrix.Length; i++) |
|
static void Main() |
Local variables must be assigned a value before they can be read.
Fields and array elements are automatically initialized with the default values for their type. The following code outputs 0, because array elements are implicitly assigned to their default values. |
|
By default, arguments in C# are passed by |
value
This means a copy of the value is created when passed to the method |
|
The ref modifier |
To pass by reference, C# provides the ref parameter modifier.
class Test { |
|
The out modifier |
An out argument is like a ref argument, except it:
class Test { lastName = name.Substring (i + 1); |
|
The params modifier |
params parameter modifier may be specified on the last parameter of a method so that the method accepts any number of parameters of a particular type. The parameter type must be declared as an array
class Test { |
|
Optional parameters |
From C# 4.0, methods, constructors, and indexers can declare optional parameters. A parameter is optional if it specifies a default value in its declaration:
Optional parameters may be omitted when calling the method:
Foo(); // 23 |
|
Named arguments |
Rather than identifying an argument by position, you can identify an argument by name. void Foo (int x, int y) { Console.WriteLine (x + ", " + y); } Named arguments can occur in any order. The following calls to Foo are semantically identical: |
|
It is often the case that you declare and initialize a variable in one step. If the compiler is able to infer the type from the initialization expression, you can use the keyword |
var
var x = "hello";
This is precisely equivalent to: |
|
Void Expressions A void expression is an expression that has no value |
A void expression is an expression that has no value. For example:
Console.WriteLine (1) |
|
Shift self left by Shift self right by And self by Exclusive-Or self by Or self by |
Shift self left by <<= Shift self right by >>= And self by &= Exclusive-Or self by ^= Or self by |
|
foreach loops |
foreach statement iterates over each element in an enumerable object. Most of the types in C# and the .NET Framework that represent a set or list of elements are enumerable
foreach (char c in "beer") // c is the iteration variable |
|
namespace |
A namespace is a domain for type names. Types are typically organized into hierarchical |
|
namespace keyword |
The namespace keyword defines a namespace for types within that block. For |
|
collision. Rather than importing the whole namespace, you can import just the specific types you need, giving each type an alias. For example: |
using PropertyInfo2 = System.Reflection.PropertyInfo; |
|
An entire namespace can be aliased, as follows |
using R = System.Reflection; |
|
Extern |
Extern aliases allow your program to reference two types with the same fully qualified |
|
The non-nested class modifiers are |
The non-nested class modifiers are public, internal, abstract, sealed, static, unsafe, partial |
|
A field is a variable that is |
a member of a class or struct. For example: |
|
readonly modifier |
readonly modifier prevents a field from being modified after construction. A read-only field can be assigned only in its declaration or within the enclosing type’s constructor. |
|
Field initialization |
Field initialization is optional. An uninitialized field has a default value. Field initializers run before constructors: |
|
Overloading constructors |
A class or struct may overload constructors. To avoid code duplication, one constructor |
|
Constructor and field initialization order |
fields can be initialized with default values in their declaration: |
|
common reason to have a nonpublic constructor |
A common reason to have a nonpublic constructor is to control instance creation via a static method call. The static method could be used to return an object from a pool rather than necessarily creating a new |
|
Properties |
Properties look like fields from the outside, but internally they contain logic, like methods do. You can’t tell by looking at the following code whether CurrentPrice is a field or a property:
Stock msft = new Stock();
A property is declared like a field, but with a get/set block added
public class Stock {
example, the set method could throw an exception if value was outside a valid range of values. |
|
Read-only properties |
A property is read-only if it specifies only a get accessor, and it is write-only if it specifies only a set accessor. Write-only properties are rarely used |
|
Automatic properties |
automatic property declaration instructs the compiler to provide this implementation. We can redeclare the first example in this section as follows: |
|
Indexers |
Indexers provide a natural syntax for accessing elements in a class or struct that encapsulate a list or dictionary of values. Indexers are similar to properties, but are accessed via an index argument rather than a property name. The string class has an indexer that lets you access each of its char values via an int index: |
|
Implementing an indexer |
To write an indexer, define a property called this, specifying the arguments in square brackets. For instance: }
Here’s how we could use this indexer: |
|
Class fields allow for the following modifiers |
Static modifier - static |
|
Methods |
A method performs an action in a series of statements. A method can receive input data from the caller by specifying parameters and output data back to the caller by specifying a return type. A method can specify a void return type, indicating that it doesn’t return any value to its caller. A method can also output data back to the caller via ref/out parameters. |
|
Methods allow the following modifiers |
Static modifier - static |
|
Overloading methods |
A type may overload methods (have multiple methods with the same name), as long as the signatures are different. void Foo (int x) {...} However, the following pairs of methods cannot coexist in the same type, since the return type and the params modifier are not part of a method’s signature: |
|
Pass-by-value versus pass-by-reference and method overloading |
Whether a parameter is pass-by-value or pass-by-reference is also part of the signature. For example, Foo(int) can coexist with either Foo(ref int) or Foo(out int). However, Foo(ref int) and Foo(out int) cannot coexist:
|
|
Instance Constructors |
Constructors run initialization code on a class or struct. A constructor is defined like a method, except that the method name and return type are reduced to the name of |
|
Instance constructors allow the following modifiers
Overloading constructors |
Access modifiers - public, internal, private, protected
A class or struct may overload constructors |
|
Implicit parameterless constructors |
For classes, the C# compiler automatically generates a parameterless public constructor if and only if you do not define any constructors. However, as soon as you define at least one constructor, the parameterless constructor is no longer automatically generated. |
|
Constructor and field initialization order |
fields can be initialized with default values in their declaration: |
|
Nonpublic constructors |
Constructors do not need to be public. A common reason to have a nonpublic constructor is to control instance creation via a static method call. The static method could be used to return an object from a pool rather than necessarily creating a new object, or return various subclasses based on input arguments: |
|
Object Initializers Versus Optional Parameters |
Instead of using object initializers, we could make Bunny’s constructor accept optional parameters:
An advantage of this approach is that we could make Bunny’s fields (or properties, as we’ll explain shortly) read-only if we choose.
The disadvantage in this approach is that each optional parameter value is baked into the calling site. In other words, C# translates our constructor call into this: |
|
Properties allow the following modifiers |
Static modifier - static |
|
CLR indexer implementation |
Indexers internally compile to methods called get_Item and set_Item, as follows: |
|
Static Constructors |
A static constructor executes once per type, rather than once per instance. A type can define only one static constructor, and it must be parameterless and have the same name as the type: class Test {
The only modifiers allowed by static constructors are unsafe and extern. |
|
Static Classes |
A class can be marked static, indicating that it must be composed solely of static members and cannot be subclassed. The System.Console and System.Math classes are good examples of static classes. |
|
Finalizers |
Finalizers are class-only methods that execute before the garbage collector reclaims the memory for an unreferenced object. The syntax for a finalizer is the name of the class prefixed with the ~ symbol: class Class1 { ~Class1() { |
|
Partial Types and Methods |
Partial types allow a type definition to be split—typically across multiple files. A common scenario is for a partial class to be auto-generated from some other source // PaymentFormGen.cs - auto-generated |
|
There are two ways to specify a base class with partial classes: |
Specify the (same) base class on each participant. For example:
Specify the base class on just one participant. For example: |
|
Inheritance |
public class Asset {
public class Stock : Asset // inherits from Asset |
|
Polymorphism |
Polymorphism works on the basis that subclasses (Stock and House) have all the |
|
Casting and Reference Conversions |
An object reference can be: |
|
The as operator |
as operator performs a downcast that evaluates to null (rather than throwing an exception) if the downcast fails: |
|
The is operator |
is operator tests whether a reference conversion would succeed; in other words, whether an object derives from a specified class (or implements an interface). It is often used to test before downcasting. |
|
Virtual Function Members explanation |
A function marked as virtual can be overridden by subclasses wanting to provide a specialized implementation. Methods, properties, indexers, and events can all be declared virtual |
|
Virtual Function Members code |
public class Asset {
public class Stock : Asset { |
|
Abstract Classes |
class declared as abstract can never be instantiated. Instead, only its concrete subclasses can be instantiated. |
|
abstract members |
Abstract classes are able to define abstract members. Abstract members are like virtual
That implementation must be provided by the subclass, unless that subclass is also |
|
abstract members code |
public abstract class Asset { |
|
Hiding Inherited Members |
A base class and a subclass may define identical members. For example:
Usually, this happens by accident and generates a warning.
Occasionally, you want to hide a member deliberately, in which case you can apply |
|
Sealing Functions and Classes |
An overridden function member may seal its implementation with the sealed keyword
You can also seal the class itself, implicitly sealing all the virtual functions, by applying
|
|
The base Keyword |
The base keyword is similar to the this keyword. It serves two essential purposes: |
|
Constructors and Inheritance |
A subclass must declare its own constructors. The base class’s constructors are accessible to the derived class, but are never automatically inherited. Any subclass must "redefine" any constructors it wants to expose., it can call any of the base class's constructors with the base keyword |
|
Implicit calling of the parameterless base-class constructor |
If a constructor in a subclass omits the base keyword, the base type’s parameterless |
|
Upcasting
Downcasting |
Upcasting
Downcasting |
|
Boxing |
Boxing is the act of converting a value-type instance to a reference-type instance. The reference type may be either the object class or an interface
int x = 9; |
|
Unboxing |
Unboxing reverses the operation, by casting the object back to the original value type:
Unboxing requires an explicit cast. The runtime checks that the stated value type matches the actual object type, and throws an InvalidCastException if the check |
|
Copying semantics of boxing and unboxing |
Boxing copies the value-type instance into the new object, and unboxing copies the contents of the object back into a value-type instance. In the following example, changing the value of i doesn’t change its previously boxed copy:
int i = 3; |
|
All types in C# are represented at runtime with an instance of System.Type. There are two basic ways to get a System.Type object |
• Call GetType on the instance.
GetType is evaluated at runtime; typeof is evaluated statically at compile time |
|
A struct can have all the members a class can, except the following |
• A parameterless constructor |
|
example of declaring and calling struct constructors |
public struct Point |
|
Friend Assemblies |
In advanced scenarios, you can expose internal members to other friend assemblies |
|
Restrictions on Access Modifiers |
Restrictions on Access Modifiers |
|
An interface is special in the following ways |
• Interface members are all implicitly abstract. In contrast, a class can provide both abstract members and concrete members with implementations. |
|
definition of the IEnumerator interface, defined in System.Collections |
public interface IEnumerator // all methods are abstract a class implementing this interface will need to provide definitions
|
|
string concatenation |
string s = "a" + "b"; |
|
Extending an Interface |
Interfaces may derive from other interfaces. For instance:
IRedoable “inherits” all the members of IUndoable. In other words, types that implement IRedoable must also implement the members of IUndoable.
|
|
Explicit Interface Implementation def |
Implementing multiple interfaces can sometimes result in a collision between member signatures. You can resolve such collisions by explicitly implementing an interface member.
int I2.Foo() { |
|
Implementing Interface Members Virtually |
An implicitly implemented interface member is, by default, sealed. It must be marked virtual or abstract in the base class in order to be overridden. |
|
Reimplementing an Interface in a Subclass |
A subclass can reimplement any interface member already implemented by a base class. |
|
In the following example, TextBox implements IUndoable.Undo explicitly, and so it cannot be marked as virtual. In order to “override” it, RichTextBox must reimplement IUndoable’s Undo method: |
public interface IUndoable { void Undo(); } |
|
design a base class such that reimplementation |
• When implicitly implementing a member, mark it virtual if appropriate. |
|
Interfaces and Boxing |
Converting a struct to an interface causes boxing. Calling an implicitly implemented member on a struct does not cause boxing: |
|
Enums |
public enum BorderSide { Left, Right, Top, Bottom } |
|
A translation between the enum types uses the |
underlying integral values: |
|
explicitly check an enum value for validity. The static Enum.IsDefined method does this job: |
BorderSide side = (BorderSide) 12345; |
|
Nested Types |
A nested type is declared within the scope of another type. For example: |
|
A nested type has the following features |
• It can access the enclosing type’s private members and everything else the enclosing type can access. |
|
Generics |
C# has two separate mechanisms for writing code that is reusable across different types: inheritance and generics.
Whereas inheritance expresses reusability with a base type, generics express reusability with a “template” that contains “placeholder” |
|
Generic Types |
A generic type declares type parameters—placeholder types to be filled in by the consumer of the generic type, which supplies the type arguments.
Stack declares a single type parameter T: We can use Stack as follows: |
|
Generic Methods |
A generic method declares type parameters within the signature of a method |
|
generic method that swaps the contents of two |
static void Swap (ref T a, ref T b) b = temp; |
|
Declaring Type Parameters |
Type parameters can be introduced in the declaration of classes, structs, interfaces,
public struct Nullable |
|
The default Generic Value |
The default keyword can be used to get the default value given a generic type parameter.
static void Zap (T[] array) |
|
Generic Constraints |
By default, a type parameter can be substituted with any type whatsoever. Constraints can be applied to a type parameter to require more specific type arguments These are the possible constraints: |
|
Subclassing Generic Types |
A generic class can be subclassed just like a nongeneric class. The subclass can leave the base class’s type parameters open, as in the following example: |
|
C#’s cast operator can perform several kinds of conversion, including: |
• Numeric conversion |
|
Covariance |
Assuming A is convertible to B, X is covariant if X<A> is convertible to X<B>.
With C#’s notion of covariance (and contravariance), “convertible” means convertible via an implicit reference conversion— such as A subclassing B, or A implementing B. Numeric conversions, boxing conversions, and custom conversions are not included. |
|
Covariance and contravariance (or simply “variance”) are advanced concepts. The motivation behind introducing and enhancing variance in C# was to |
allow generic interface and generic types (in particular, those defined in the Framework, such as IEnumerable<T>) to work more as you’d expect. You can benefit from this without understanding the details behind covariance |
|
array types are covariant |
For historical reasons, array types are covariant. This means that B[] can be cast to |
|
Contravariance |
We previously saw that, assuming that A allows an implicit reference conversion to B, a type X is covariant if X<A> allows a reference conversion to X<B>. A type is contravariant when you can convert in the reverse direction—from X<B> to X<A>. |
|
consider the Max method in C#, once more: |
The reason is that Max needs to be compiled once and work for all possible values of T. Compilation cannot succeed, because there is no single meaning for > across all values of T—in fact, not every T even has a > operator. In contrast, the following code shows the same Max method written with C++ templates. This code will be compiled separately for each value of T, |
|
Delegates def |
A delegate is an object that knows how to call a method. |
|
The following defines a delegate type called Transformer: |
delegate int Transformer (int x); Transformer is compatible with any method with an int return type and a single int parameter, such as this: Assigning a method to a delegate variable creates a delegate instance: |