C# 7.0 Flashcards
What is the purpose of the readonly modifier when applied to a field in a class or struct?
It means the field’s value cannot be modified after the class’ constructor is called.
When are initialisers run for fields and in what order are the initialisers run?
Field initialisers run before the object’s constructor runs, and they run in order of the corresponding field declarations from top to bottom.
What must always remain true of all method declarations in a class in order for those methods to coexist in the same class?
No two methods can have the same signature in the same class. That is, they cannot have both the same name and number of parameters in the same type order (names don’t matter), even if their return types are different.
When can an expression-bodied member be used and what is an example of the syntax?
An expression-bodied member can be used when a method’s body comprises a single expression, e.g.
int doubleMe(int x) => 2 * x;
or
void printMe(string x) => Console.WriteLine(x);
Why would neither of the following pairs of methods compile?
void Foo(int x) { ... } float Foo(int x) { ... }
void Bar(int[] x) void Bar(params int[] x)
- The two methods named Foo have the same name and parameter type order, so the compiler cannot differentiate them when being called, even though their declarations have different return types.
- The two methods named Bar cannot coexist because the params modifier is not considered by the compiler (as, in the end, the params in Bar’s second declaration would be collected into an int[] and then be identical to Bar’s first declaration).
Which of the following pairs of method declarations can exist together, and why does introducing the third one cause a compile-time error in each case?
void Foo(int x) { ... } float Foo(ref int x) { ... } void Foo(out int x) { ... }
- The first and second can coexist as the ref parameter is considered a modifier for the parameter list, so it is still well-defined. Introducing the third method causes a compile-time error as the compiler does not distinguish ref and out parameters in the same position.
- The first and third methods can coexist as the out parameter is considered a modifier too. Introducing the second method causes a compile-time error for the same reason.
What is the syntax for calling one overload of a class/struct constructor from a second overload of that constructor? Which of the two constructors is called first?
Using the ‘this’ keyword:
public class Foo { public Foo(int x) { ... } public Foo(int x, int y) : this(x) { ... } }
In this case, the FIRST constructor (the one called by ‘this’) is executed first.
Under what conditions are implicit parameterless constructors automatically defined by the compiler?
When, and only when, the class has no explicit constructors defined. As soon as one is defined, the compiler no longer generates one automatically.
What are deconstructors [C# 7.0] and how must they be declared in a class and used in a calling type?
- Deconstructors take fields/properties from a class and assign them to variables specified by the calling type.
- They must be named Deconstruct and must be have one or more ‘out’ parameters.
- When being called, they can be assigned to a tuple matching the same type order (or be implicitly typed), or by explicitly calling Deconstruct and specifying out parameters. Examples:
(var width, var height) = rectangle;
var (width, height) = rectangle; // Big brain syntax sugar
(width, height) = rectangle; // Assuming width, height already declared
What is an object initializer and when is it called in relation to the constructor of a class when it is used?
- An object initialiser allow you to set fields in a class during the construction of an object, e.g.
var foo = new Foo { x = 1, y = 2 }; // Omit ( ) for default constructor var foo2 = new Foo(x, y) { z = 3 };
- The fields that are set by an initialiser are set AFTER the constructor executes.
Where are two places the ‘this’ keyword CANNOT be used in a class?
- It cannot be used in any static members of a class
- It cannot be used in an expression passed to a constructor overload in the declaration of another overload, e.g.
public Foo(int x); public Foo(int x, int y) : this(this.X); // Will not compile
What is the GENERAL syntax for declaring a property with a backing field?
private decimal currentPrice; // Backing field
public decimal CurrentPrice { get { return currentPrice; } set { currentPrice = value; } // value is an implicit argument name }
How is an expression-bodied property [C# 6.0] interpreted by the C# compiler?
An expression-bodied property is interpreted as a read-only property. As an example:
public double NormalisedValue => rawValue / magnitude;
is equivalent to
public double NormalisedValue
{
get { return rawValue / magnitude };
}
How can expression-bodied properties be used to implement properties that are neither read nor write only?
Example
public int MyProperty { get => myBackingField; set => myBackingField = value; }
How is an automatic property declared and how can its automatically-generated backing field be used?
- They are declared by specifying a property with a ‘get’ and/or ‘set’ with no implementation:
public int MyPubReadPrivateWriteProp { get; private set; }
public int MyReadOnlyProp { get; }
public int MyWriteOnlyProp { set; }
- You cannot refer to the automatically-generated backing field the compiler generates for an automatic property
Will the following line of code compile?
public readonly int Maximum { get; } = 999;
Yes, as
- Properties can have initialisers in the same way that fields can
- Properties have the same readonly behaviour as fields
Assuming MyType has an appropriate indexer implemented, will the following type compile and execute without any exceptions?
MyType myInst;
var myIndex = “foo”
Console.WriteLine(myInst?[myIndex])
Yes, as:
- The index can be any of any type, not just an integer
- Indexers can be called using the null-conditional, so using “?” on a null reference will simply result in the expression being null
How would an indexer be broadly implemented for a class?
By declaring a property named ‘this’, e.g.
public string this[int index] { get { ... } set { ... } }
What the following class compile, why or why not?
public class MyClass { public string this[int x] { get { ... } set { ...} } public string this[int x, int y] { get { ... } set { ...} } public string this[bool y] => ... }
Yes, as
- A class can have multiple indexers, as long as they have unique signatures for their index arguments
- An an indexer can accept more than one index argument
- Indexers can be expression bodied, in which case they are interpreted like read-only properties internally
What are two ways that a constant is different from a static readonly field?
- Constants must be initialised in their declaration, unlike readonly properties that can be initialised in a static constructor
- The value a constant takes must itself be a constant expression (as it is evaluated at compile time)