C# Specification Flashcards

1
Q

Describe the type system

A

The type system in C# is a unified type system and has 2 types. Value types and references types. All types including user-defined references types and value types inherit from the same root type called “object”. The root type provides a common set of operations which allows all types to be stored, transported and operated upon in a consistent manner.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Program structure

A

C# programs consist of source files which contain type declarations and members organized in namespaces. When compiled, executable code in the form of Intermediate Language instructions and metadata are generated from the types and packaged into either application (.exe) or library (.dll) assemblies.

When executed, the IL code is converted into processor-specific code by the Just-In-Time (JIT) compiler from the .NET Common Language Runtime.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Describe value types

A

A value type variable directly contains the data and is stored on the stack. Value type variables have their own copy of the data and operations on variables do not affect one another. Therefore, when passing a value type to a method, the method receives a copy of the variable value by default. However, ref and out parameter variables can be used to share variables across different scopes.

Value types consist of

Simple types
Signed integral: sbyte, short, int, long
Unsigned integral: byte, ushort, uint, ulong
Unicode characters: char
IEEE floating point: float, double
High-precision decimal: decimal
Boolean: bool
Enum types
User-defined types of the form enum E {…}
Struct types
User-defined types of the form struct S {…}
Nullable types
Extensions of all other value types with a null value

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Describe reference types

A

A reference type variable contains a reference to it’s data which is stored on the heap. Multiple reference type variables can reference the same object and therefore can have an affect on one another.

Reference types consist of

Class types	
     Ultimate base class of all other types: object
     Unicode strings: string
     User-defined types  of the form class C {...}
Interface types	
     User-defined types of the form interface I {...}
Array types	
     Single- and multi-dimensional, for example, int[] and int[,]
Delegate types	
     User-defined types of the form e.g. delegate int D(...)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Numeric types

A
Signed integral	
8	sbyte	-128...127
16	short	-32,768...32,767
32	int	-2,147,483,648...2,147,483,647
64	long	-9,223,372,036,854,775,808...9,223,372,036,854,775,807
Unsigned integral	
8	byte	0...255
16	ushort	0...65,535
32	uint	0...4,294,967,295
64	ulong	0...18,446,744,073,709,551,615

Floating point
32 float 1.5 × 10^−45 to 3.4 × 10^38, 7-digit precision
64 double 5.0 × 10^−324 to 1.7 × 10^308, 15-digit precision

Decimal
128 decimal 1.0 × 10^−28 to 7.9 × 10^28, 28-digit precision

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Struct vs. Class

A

Structs are values types and classes are reference types. Structs and Classes both inherit from object and contain members (fields, methods, properties and constructors) but, structs do not support user-defined inheritance and polymorphism although they can implement interfaces. Structs can also be assigned a null value which allows for Nullables.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Describe Boxing and Unboxing

A

Since C# has a unified type system, every type including all values types inherit from object. This allows for values types to be converted into reference types and back to values types. Boxing is converting a value type to an object (a reference type) and Unboxing is converting a reference type to a value type. This conversion does have a performance impact in that the data is being copied from the stack to the heap or from the heap to the stack.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

What is a Nullable value type?

A

Value types are made nullable by wrapping them in the Nullable struct such as Nullable. Nullable and int? are identical declarations. You can also make a struct Nullable the same way i.e. Nullable or MyStruct? The Nullable adds 2 properties HasValue and Value. HasValue is a flag that keeps tract of whether a value has been assigned or not. If HasValue is false then access the Value property will result in and exception. Even though Nullable is a struct and therefore a value type, the null value can be assigned with the help of special rules in the compiler.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Type Pattern matching with ‘is’:

What is the result of this expression?

int? a = 42;
if (a is int valueOfA)
{
    Console.WriteLine($"a is {valueOfA}");
}
else
{
    Console.WriteLine("a does not have a value");
}
A

a is 42

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Type Pattern matching with ‘is’:

What is the result of this expression?

int? a = null;
if (a is int valueOfA)
{
    Console.WriteLine($"a is {valueOfA}");
}
else
{
    Console.WriteLine("a does not have a value");
}
A

a does not have a value

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

checked and unchecked

A

C# statements can execute in either checked or unchecked context. In a checked context, arithmetic overflow raises an exception. In an unchecked context, arithmetic overflow is ignored and the result is truncated by discarding any high-order bits that don’t fit in the destination type.

The following operations are affected by the overflow checking:

Expressions using the following predefined operators on integral types:

++, –, unary -, +, -, *, /

Explicit numeric conversions between integral types, or from float or double to an integral type.

If neither checked nor unchecked is specified, the default context for non-constant expressions (expressions that are evaluated at run time) is defined by the value of the -checked compiler option. By default the value of that option is unset and arithmetic operations are executed in an unchecked context.

For constant expressions (expressions that can be fully evaluated at compile time), the default context is always checked. Unless a constant expression is explicitly placed in an unchecked context, overflows that occur during the compile-time evaluation of the expression cause compile-time errors.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Describe class member Accessibility

A

All types and type members have an accessibility level. The accessibility level controls whether they can be used from other code in your assembly or other assemblies. Use the following access modifiers to specify the accessibility of a type or member when you declare it:

public - The type or member can be accessed by any other code in the same assembly or another assembly that references it.

private - The type or member can be accessed only by code in the same class or struct.

protected - The type or member can be accessed only by code in the same class, or in a class that is derived from that class.

internal - The type or member can be accessed by any code in the same assembly, but not from another assembly.

protected internal - The type or member can be accessed by any code in the assembly in which it’s declared, or from within a derived class in another assembly.

private protected - The type or member can be accessed only within its declaring assembly, by code in the same class or in a type that is derived from that class.

none - defaults to internal

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

ref vs. out

A

Ref and out keywords in C# are used to pass arguments within a method or function. Both indicate that an argument/parameter is passed by reference. By default parameters are passed to a method by value. By using these keywords (ref and out) we can pass a parameter by reference.

Ref:

  • The parameter or argument must be initialized first before it is passed to ref.
  • It is not required to assign or initialize the value of a parameter (which is passed by ref) before returning to the calling method.
  • Passing a parameter value by Ref is useful when the called method is also needed to modify the pass parameter.
  • It is not compulsory to initialize a parameter value before using it in a calling method.
  • When we use REF, data can be passed bi-directionally.

Out:

  • It is not compulsory to initialize a parameter or argument before it is passed to an out.
  • A called method is required to assign or initialize a value of a parameter (which is passed to an out) before returning to the calling method.
  • Declaring a parameter to an out method is useful when multiple values need to be returned from a function or method.
  • A parameter value must be initialized within the calling method before its use.
  • When we use OUT data is passed only in a unidirectional way (from the called method to the caller method).
  • Both ref and out are treated differently at run time and they are treated the same at compile time.
  • Properties are not variables, therefore it cannot be passed as an out or ref parameter.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Instance Constructor vs. Static Constructor

A

An instance constructor is a member that implements the actions required to initialize an instance of a class. A static constructor is a member that implements the actions required to initialize a class itself when it is first loaded.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Describe Indexers

A

An indexer is a member that enables objects to be indexed in the same way as an array. An indexer is declared like a property except that the name of the member is this followed by a parameter list written between the delimiters [ and ].

class SampleCollection
{
   // Declare an array to store the data elements.
   private T[] arr = new T[100];
   // Define the indexer to allow client code to use [] notation.
   public T this[int i]
   {
      get { return arr[i]; }
      set { arr[i] = value; }
   }
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Describe Events

A

An event is a member that enables a class or object to provide notifications. An event is declared like a field except that the declaration includes an event keyword and the type must be a delegate type.

17
Q

Describe Destructors

A

A destructor is a member that implements the actions required to destruct an instance of a class. Destructors cannot have parameters, they cannot have accessibility modifiers, and they cannot be invoked explicitly. The destructor for an instance is invoked automatically during garbage collection.

The garbage collector is allowed wide latitude in deciding when to collect objects and run destructors. Specifically, the timing of destructor invocations is not deterministic, and destructors may be executed on any thread. For these and other reasons, classes should implement destructors only when no other solutions are feasible.

The using statement provides a better approach to object destruction.

18
Q

Describe Interfaces

A

An interface defines a contract that can be implemented by classes and structs. An interface can contain methods, properties, events, and indexers. An interface does not provide implementations of the members it defines—it merely specifies the members that must be supplied by classes or structs that implement the interface.

19
Q

What is an Explicit Interface Member Implementation

A

An explicit interface member implementation is written using the fully qualified interface member name. Explicit interface members can only be accessed via the interface type.

public class EditBox: IControl, IDataBound
{
    void IControl.Paint() {...}
    void IDataBound.Bind(Binder b) {...}
}
EditBox editBox = new EditBox();
editBox.Paint();                        // Error, no such method
IControl control = editBox;
control.Paint();                        // Ok
20
Q

Describe an Enum’s underlying type

A

Each enum type has a corresponding integral type called the underlying type of the enum type. An enum type that does not explicitly declare an underlying type has an underlying type of int. An enum type’s storage format and range of possible values are determined by its underlying type. The set of values that an enum type can take on is not limited by its enum members. In particular, any value of the underlying type of an enum can be cast to the enum type and is a distinct valid value of that enum type.

Example of an explicitly defined underlying type

enum Alignment: sbyte
{
    Left = -1,
    Center = 0,
    Right = 1
}
21
Q

Describe Delegates

A

A delegate type represents references to methods with a particular parameter list and return type. Delegates make it possible to treat methods as entities that can be assigned to variables and passed as parameters. Delegates are similar to the concept of function pointers found in some other languages, but unlike function pointers, delegates are object-oriented and type-safe.

22
Q

Describe Expression-bodied function members

A

Many members that you write are single statements that could be single expressions. Write an expression-bodied member instead. It works for methods and read-only properties. For example, an override of ToString() is often a great candidate:

public override string ToString() => $”{LastName}, {FirstName}”;

23
Q

Keyword: unsafe

A

The unsafe keyword denotes an unsafe context, which is required for any operation involving pointers.

unsafe static void FastCopy(byte[] src, byte[] dst, int count)
{
    // Unsafe context: can use pointers here.
}

or

unsafe
{
    // Unsafe context: can use pointers here.
}
24
Q

Keyword: fixed

A

The fixed statement prevents the garbage collector from relocating a movable variable. The fixed statement is only permitted in an unsafe context

The fixed statement sets a pointer to a managed variable and “pins” that variable during the execution of the statement. Pointers to movable managed variables are useful only in a fixed context. Without a fixed context, garbage collection could relocate the variables unpredictably. The C# compiler only lets you assign a pointer to a managed variable in a fixed statement.

class Point
{
    public int x;
    public int y;
}
unsafe private static void ModifyFixedStorage()
{
    // Variable pt is a managed variable, subject to garbage collection.
    Point pt = new Point();
    // Using fixed allows the address of pt members to be taken,
    // and "pins" pt so that it is not relocated.
    fixed (int* p = &pt.x)
    {
        *p = 1;
    }
}
25
Q

Describe Attributes

A

Attributes allow developers to create declarative information and decorate various program entities which can then be retrieved at runtime.

Attributes are defined through the declaration of attribute classes (Attribute classes), which may have positional and named parameters (Positional and named parameters). Attributes are attached to entities in a C# program using attribute specifications (Attribute specification), and can be retrieved at run-time as attribute instances (Attribute instances).

Attribute usage
The attribute AttributeUsage (The AttributeUsage attribute) is used to describe how an attribute class can be used.

AttributeUsage has a positional parameter (Positional and named parameters) that enables an attribute class to specify the kinds of declarations on which it can be used.

using System;

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)]
public class SimpleAttribute: Attribute 
{
    ...
}