Puzles C#

94
#dotNETSpain2015 Leo Antoli @lantoli Puzzles C# .NET Conference 2015 Y A X B

Transcript of Puzles C#

Page 1: Puzles C#

#dotNETSpain2015

Leo Antoli @lantoliPuzzles C#

.NET Conference 2015

Y

AX B

Page 2: Puzles C#

#dotNETSpain2015

Page 3: Puzles C#

#dotNETSpain2015

Equals & ==

string s1 = "hello";

string s2 = "HELLO".ToLower();

object o1 = s1;

object o2 = s2;

1) s1 == s2 2) o1 == o2 3) s1 == o2

4) s1.Equals(s2) 5) s1.Equals(o2) 6) o1.Equals(s2)

A) All true

B) All == false, All Equals true

C) 1 & 4 true, else false

D) Other

Page 4: Puzles C#

#dotNETSpain2015

Equals & ==

D) Other

1) s1 == s2 true

2) o1 == o2 false

3) s1 == o2 false

4) s1.Equals(s2) true

5) s1.Equals(o2) true

6) o1.Equals(s2) true

Equals is overridden (runtime)

Static methods can only be overloaded (compile time)

Page 5: Puzles C#

#dotNETSpain2015

Equals semantics

double n = double.NaN;

Console.WriteLine(n == n);

Console.WriteLine(n.Equals(n));

A) False False

B) False True

C) True False

D) True True

Page 6: Puzles C#

#dotNETSpain2015

Equals semantics

B) False True

== semantics can be less strict, and it’s normally used for referential

equality.

Equals semantics is expected to be an equivalence relationship:

- Reflexive (a equals a)

- Commutative (a equals b implies b equals a)

- Transitive (a equals b and b equals c implies a equals c)

Page 7: Puzles C#

#dotNETSpain2015

Enumerable equals

IEnumerable<string> list1 = new List<String> {"a", "b"};

IEnumerable<string> list2 = new List<String> { "b", "a" };

IEnumerable<string> list3 = new List<String> { "a", "b" };

Console.WriteLine(list1.Equals(list2));

Console.WriteLine(list1.SequenceEqual(list2));

Console.WriteLine(list1.Equals(list3));

Console.WriteLine(list1.SequenceEqual(list3));

A) False False False True

B) False False True True

C) True False True True

D) Other

Page 8: Puzles C#

#dotNETSpain2015

Enumerable equals

A) False False False True

Equals in lists is not overridden, so it only compares whether list

references are equals.

SequenceEqual check the enumerables have the same count and the

same elements in the same order.

If order is not important, you can sort the lists, create sets and use

SetEquals (if duplicates are not important), etc.

Page 9: Puzles C#

#dotNETSpain2015

Inheritance override

interface Inter { void Message(); }

class A : Inter {

public void Message() { Console.WriteLine("A"); }}

class B : A {

public new void Message() { Console.WriteLine("B"); }}

B b = new B();

((Inter)b).Message();

((A)b).Message();

A) Displays A A

B) Displays A B

C) Displays B A

D) Displays B B

Page 10: Puzles C#

#dotNETSpain2015

Inheritance override

A) Displays A A

A.Message is sealed (default modifier)

B.Message is a new method (no override)

Inter.Message is implemented by A.Message because B does not

explicitly implements Inter

Avoid "new" to redefine methods.

Page 11: Puzles C#

#dotNETSpain2015

Overload choice 1

class A { public void Print(int n) {

Console.WriteLine("A"); }

class B : A { public void Print(double n) {

Console.WriteLine("B"); }

...

var b = new B();

b.Print(10);

A) Displays A

B) Displays B

C) Compilation error

D) Other

Page 12: Puzles C#

#dotNETSpain2015

Overload choice 1

B) Displays B

First methods in the current class are tried to be called. As an implicit conversion from int to double

exists, it is called.

Page 13: Puzles C#

#dotNETSpain2015

Overload choice 2

void Hello(double a) { Console.WriteLine("double"); }

void Hello<T>(T a) { Console.WriteLine("T"); }

...

Hello(10);

A) Displays double

B) Displays T

C) Compilation error

D) Other

Page 14: Puzles C#

#dotNETSpain2015

Overload choice 2

B) Displays T

Overload with existing methods in the class is tried before implicit casting.

Page 15: Puzles C#

#dotNETSpain2015

Enum

enum Quarter { Q1 = 1, Q2 = 2, Q3 = 3, Q4 = 4 };

class Invoice {

public Quarter CurrentQuarter { get; set; }

}

Invoice invoice = new Invoice();

Console.WriteLine(invoice.CurrentQuarter);

A) Displays Q1

B) Displays 0

C) Runtime exception

D) Other

Page 16: Puzles C#

#dotNETSpain2015

Enum

B) Displays 0

Value types are always initialised to 0

Provide always a 0 enum element.

Page 17: Puzles C#

#dotNETSpain2015

Assignment compatibility

uint[] foo = new uint[10];

object bar = foo;

foo is uint[] // True

foo is int[] // ???

bar is uint[] // True

bar is int[] // ???

A) False False

B) False True

C) True False

D) True True

Page 18: Puzles C#

#dotNETSpain2015

Assignment compatibility

B) False True

The CLI has the concept of "assignment compatibility"... The assignment from source value to

target variable has to be "representation preserving".

One of the rules of the CLI is "if X is assignment compatible with Y then X[] is assignment

compatible with Y[]".

That is not a rule of C#. C#'s array covariance rule is "if X is a reference type implicitly

convertible to reference type Y (via a reference or identity conversion) then X[] is implicitly

convertible to Y[]". That is a subtly different rule!

http://blogs.msdn.com/b/ericlippert/archive/2009/09/24/why-is-covariance-of-value-typed-

arrays-inconsistent.aspx

Page 19: Puzles C#

#dotNETSpain2015

Unboxing

short s = 123;

object o = s;

int i = (int)o;

A) i = 123

B) Compilation error

C) Runtime exception

D) Other

Page 20: Puzles C#

#dotNETSpain2015

C) Runtime exception

int i = (int)(short)o is OK

InvalidCastException. A boxed T can only be unboxed to Thttp://blogs.msdn.com/b/ericlippert/archive/2009/03/19/representation-and-identity.aspx

Unboxing

Page 21: Puzles C#

#dotNETSpain2015

Tryparse

int res;

bool success =

int.TryParse("1", (NumberStyles)1111, null, out res);

Console.WriteLine(success);

Console.WriteLine(res);

A) Displays True 1

B) Displays False 0

C) Runtime exception

D) Other

Page 22: Puzles C#

#dotNETSpain2015

Tryparse

C) Runtime exception

ArgumentException: An undefined NumberStyles value is being

used.

Tryparse doesn't throw FormatException,

ArgumentNullException or OverflowException, but it

can throw ArgumentException.

Page 23: Puzles C#

#dotNETSpain2015

Checked / Unchecked

int Square(int n) { return n*n; }

...

int a = 1000000;

checked {

Console.WriteLine(Square(a));

}

A) OverflowException

B) Displays a positive number

C) Displays a negative number

D) Other

Page 24: Puzles C#

#dotNETSpain2015

Checked / Unchecked for methods

C) Displays a negative number

The effect is in the code used to emit IL instructions for integer add / subtract / multiply / data conversions inside the block.

Use settings to enable "checked" by default

Page 25: Puzles C#

#dotNETSpain2015

Using

using System;

using System.Collections.Generic;

using MyStringList = System.Collections.Generic.List<string>;

var a = new List<String>();

var b = new MyStringList();

Console.WriteLine(a.GetType() == b.GetType());

A) Displays True

B) Displays False

C) Compilation error

D) Other

Page 26: Puzles C#

#dotNETSpain2015

Using

A) Displays True

Using is an alias. In CLR using or namespaces don't

exist. Full-qualified names are always used in CLR.

Page 27: Puzles C#

#dotNETSpain2015

Basic numbers

Int32 int1 = 10;

Int64 long1 = 10;

int int2 = 10;

long long2 = 10;

Console.WriteLine(int2.GetType());

Console.WriteLine((int1 is Int32) && (long1 is Int64));

Console.WriteLine((int1 is Int64) || (long1 is Int32));

A) Displays int True False

B) Displays System.Int32 True False

C) Displays System.Int32 True True

D) Other

Page 28: Puzles C#

#dotNETSpain2015

Basic numbers

B) Displays System.Int32 True False

int is an alias for System.Int32, long for System.Int64

Int32 and Int64 are not inheritance-related

Page 29: Puzles C#

#dotNETSpain2015

Internal classes

namespace MyNamespace {

class A {

private int a;

class Internal {

void DoSomething(A arg) {

arg.a = 10;

} } }

class B {

void DoSomething(A arg) {

arg.a = 10;

} } }

A) Compiles OK

B) Compilation error in Internal

C) Compilation error in B

D) Both compilation errors

Page 30: Puzles C#

#dotNETSpain2015

Internal classes

C) Compilation error in B

Internal classes have access to private members

Page 31: Puzles C#

#dotNETSpain2015

Interface member modifiers

interface IExample

{

public void Do1();

internal void Do2();

}

A) Compiles OK

B) Compilation error in Do1

C) Compilation error in Do2

D) Both compilation errors

Page 32: Puzles C#

#dotNETSpain2015

Interface member modifiers

D) Both compilation errors

All interface members are public. Modifiers can

not be used.

Page 33: Puzles C#

#dotNETSpain2015

Overriding member modifiers

class A { protected virtual void Do1() {} }

class B : A { public override void Do1() { } }

class C : A { private override void Do1() { } }

A) Compiles OK

B) Compilation error in B

C) Compilation error in C

D) Both compilation errors

Page 34: Puzles C#

#dotNETSpain2015

Overriding member modifiers

D) Both compilation errors

The original member and the overriding

member must have the same accesiblity.

CLR allows to increase visibility but not C#

compiler.

Page 35: Puzles C#

#dotNETSpain2015

Virtual methods in ctor 1

class A {

public A() { Setup(); }

protected virtual void Setup() { }

}

class B : A {

private int i;

public B() { i = 5; }

protected override void Setup() {

Console.WriteLine(i);

} } ...

new B()

A) Displays 0

B) Displays 5

C) Runtime error

D) Other

Page 36: Puzles C#

#dotNETSpain2015

Virtual methods in ctor 1

A) Displays 0

Base constructors are called first.

Page 37: Puzles C#

#dotNETSpain2015

Virtual methods in ctor 2

class A {

public A() { Setup(); }

protected virtual void Setup() { }

}

class B : A {

private int i = 5;

public B() { }

protected override void Setup() {

Console.WriteLine(i);

} } ...

new B()

A) Displays 0

B) Displays 5

C) Runtime error

D) Other

Page 38: Puzles C#

#dotNETSpain2015

Virtual methods in ctor 2

B) Displays 5

Inline initializations are done before calling base

constructors.

Page 39: Puzles C#

#dotNETSpain2015

Partial classes

partial class A {

public void DoSomething() {

Console.Write("BEGIN ");

PartialMethod();

Console.Write("END");

}

partial void PartialMethod();

}}

new A().DoSomething();

A) Compilation error

B) Displays BEGIN and then

runtime error

C) Displays BEGIN END

D) Other

Page 40: Puzles C#

#dotNETSpain2015

Partial classes

C) Displays BEGIN END

Partial methods are not required to be implemented, in that

case it’s as if they were empty.

Page 41: Puzles C#

#dotNETSpain2015

Type Constructors

class A {

static A() { throw new Exception("Error"); } }

class B : A {

static B() { Console.WriteLine("STATIC CTOR B"); } }

...

new StaticB();

A) Displays STATIC CTOR B

B) Displays STATIC CTOR B and then runtime error

C) Runtime error, nothing is displayed

D) Other

Page 42: Puzles C#

#dotNETSpain2015

Type Constructors

B) Displays STATIC CTOR B and then runtime error

Type ctors are called before type is used so “new B()” makes B type

ctor to be called.

Derived constructors call base ctor (explicitly or implicitly). So when B

ctor calls A ctor, first A type ctor is executed.

When a type ctor throws an exception that type remains unusable.

A type ctor is not called if not used.

Page 43: Puzles C#

#dotNETSpain2015

Param execution order

public class A {

public void Do(int x, int y) {}

public static int Display(int n) { Console.WriteLine(n);

return n; }}…

var a = new A();

a.Do(y: A.Display(2), x: A.Display(1));

A) Displays 1 2

B) Displays 2 1

C) Compilation error

D) Other

Page 44: Puzles C#

#dotNETSpain2015

Param execution order

B) Displays 2 1

Parameters are evaluated from left to right, although the call is

always done by position when IL is emitted.

Page 45: Puzles C#

#dotNETSpain2015

Var params

public static void Do(int a, params string[] strs) {

Console.WriteLine(strs.Length); }...

Do(10); Do(10, "hello"); Do(10, "hello", "there");

Do(10, new []{"hello", "there"});

Do(10, (string)null);

Do(10, null);

A) Compilation error

B) Runtime error

C) Displays 0 1 2 2 1 1

D) Other

Page 46: Puzles C#

#dotNETSpain2015

Var params

B) Runtime error

Displays 0 1 2 2 1 1 and then

NullReferenceException in: Do(10, null)

Variable params can be null.

Page 47: Puzles C#

#dotNETSpain2015

Generics inference 1

public List<T> InitList<T>(T initValue) {

return new List<T> { initValue };

} ...

IList<string> list1 = new List<string> {"hello"};

IList<string> list2 = new List<> { "hello" };

IList<string> list3 = InitList("hello");

A) Compilation error only in list1

B) Compilation error only in list2

C) Compilation error only in list3

D) Other

Page 48: Puzles C#

#dotNETSpain2015

Generics inference 1

B) Compilation error only in list2

Inference only works in generic methods.

Page 49: Puzles C#

#dotNETSpain2015

Generics inference 2

public List<T> CreateList<T>() {

return new List<T>();

}…

IList<string> list1 = new List<string>();

IList<string> list2 = new List<>();

IList<string> list3 = CreateList();

A) Compilation error only in list1

B) Compilation error only in list2

C) Compilation error only in list3

D) Other

Page 50: Puzles C#

#dotNETSpain2015

Generics inference 2

D) Other

Compilation error in list2 and list3

Inference only works in generic methods, but only for input params.

Example to choose method:

IList<string> list3 = CreateList<string>();

Page 51: Puzles C#

#dotNETSpain2015

Dynamic

void Sum(int a, int b) { Console.WriteLine("{0} and {1} is {2}", a, b, a+b); }

void SumDyn(dynamic a, dynamic b) { Console.WriteLine("{0} and {1} is {2}", a, b,

a+b); }…

dynamic a1 = 10, b1 = 20; Sum(a1, b1);

dynamic a2 = 10.2, b2 = 20.3; Sum(a2, b2);

int a3 = 11, b3 = 22; SumDyn(a3, b3);

double a4 = 11.2, b4 = 22.5; SumDyn(a4, b4);

A) Compilation or runtime error in a1,b1

B) Compilation or runtime error in a2,b2

C) Compilation or runtime error in a3,b3

D) Compilation or runtime error in a4,b4

Page 52: Puzles C#

#dotNETSpain2015

Dynamic

B) Compilation or runtime error in a2,b2

RuntimeBinderException

The best overloaded methods has invalid arguments.

Page 53: Puzles C#

#dotNETSpain2015

Explicit interfaces

void PrintBool1(IConvertible obj) {

Console.WriteLine(obj.ToBoolean(null)); }

void PrintBool2(int obj) {

Console.WriteLine(obj.ToBoolean(null)); }...

int a = -3; PrintBool1(a); PrintBool2(a);

A) Displays True True

B) Displays False False

C) Runtime error

D) Other

Page 54: Puzles C#

#dotNETSpain2015

Explicit interfaces

D) Other

Compilation error in PrintBool2: int does not contain ToBoolean

IConvertible is implemented in basic numerical types as EIMI (Explicit

Interface Method Implementation)

Page 55: Puzles C#

#dotNETSpain2015

LINQ 1

int[] list = {0, 1, 2};

var res = list.Where(n => n%2 == 0).

Select(n => n*2).

Any(n => n >= 8);

list[0] = 4;

Console.WriteLine(res);

A) Displays True

B) Displays False

C) Runtime error

D) Other

Page 56: Puzles C#

#dotNETSpain2015

LINQ 1

B) Displays False

LINQ queries can be local or interpreted.

Local queries are lazy evaluated except:

- Conversions: ToList, ToArray, etc.

- Elements: First, FirstOrDefault, Last, etc.

- Aggregations: Sum, Min, Max

- Quantifiers: Any, All, Contains, etc.

Page 57: Puzles C#

#dotNETSpain2015

LINQ 2

var list = new int[] {};

Console.WriteLine( list.All(x => x > 10) );

Console.WriteLine( ! list.Any(x => x > 10) );

A) False False

B) False True

C) True False

D) True True

Page 58: Puzles C#

#dotNETSpain2015

LINQ 2

D) True True

If you don't have any test in you app, all your tests pass because you

don’t have any failing test ;-)

Page 59: Puzles C#

#dotNETSpain2015

Delegates 1

Predicate<string> containsHello = s => s.Contains("hello");

Console.WriteLine(containsHello is Predicate<string>);

Console.WriteLine(containsHello is object);

Console.WriteLine(containsHello is MulticastDelegate);

Console.WriteLine(containsHello is Delegate);

Console.WriteLine(containsHello(“hello world”);

Console.WriteLine(containsHello.Invoke(“hello world”);

A) Displays all True

B) Displays at least one False

C) Runtime error

D) Compilation error

Page 60: Puzles C#

#dotNETSpain2015

Delegates 1

A) Displays all True

Delegates are “syntactic sugar” to create a

MulticastDelegate class.

Page 61: Puzles C#

#dotNETSpain2015

Delegates 2

class Vehicle, class Terrestrial : Vehicle ,

class Car : Terrestrial…

Predicate<Terrestrial> predT = t => t.numWheels() == 2;

Predicate<Car> predCar = predT;

Predicate<Vehicle> predVehicle = predT;

A) predCar and predVehicle are OK

B) Compilation error in predCar and predVehicle

C) Compilation error only in predVehicle

D) Compilation error only in predCar

Page 62: Puzles C#

#dotNETSpain2015

Delegates 2

C) Compilation error only in predVehicle

See next puzzle...

Page 63: Puzles C#

#dotNETSpain2015

Delegates 3

class Vehicle, class Terrestrial : Vehicle ,

class Car : Terrestrial…

Func<Terrestrial> fnT = () => new Terrestrial();

Func<Car> fnCar = fnT;

Func<Vehicle> fnVechicle = fnT;

A) fnCar and fnVehicle are OK

B) Compilation error in fnCar and fnVehicle

C) Compilation error only in fnVehicle

D) Compilation error only in fnCar

Page 64: Puzles C#

#dotNETSpain2015

Delegates 3

D) Compilation error only in fnCar

Delegates can be covariant in generic type params if they’re only in

output positions and contravariant if they’re only in input positions.

Covariant (out) - a base class can be used

Contravariant (in) - a derived class can be used

public delegate bool Predicate<in T>(T obj)

public delegate TResult Func<out TResult>()

public delegate TResult Func<in T, out TResult>(T arg)

public delegate void Action<in T>(T obj)

Page 65: Puzles C#

#dotNETSpain2015

Delegates 4

Predicate<string> pred = null;

Predicate<string> predH = s => s.StartsWith("h");

pred += predH;

pred += s => s.StartsWith("a");

pred += predH;

Console.WriteLine(pred("hello"));

A) Displays True

B) Displays False

C) Compilation error

D) Runtime error

Page 66: Puzles C#

#dotNETSpain2015

Delegates 4

A) Displays True

Delegates can have multiple functions, all are executed in order and

the result of the last function is returned.

Can be duplicated functions, they’re all still executed.

Page 67: Puzles C#

#dotNETSpain2015

Delegates 5

Action<string> action = null;

action += s => { Console.WriteLine("first"); };

action += s => { throw new Exception("error"); };

action += s => { Console.WriteLine("last"); };

action("test");

A) Displays “first” and “last”

B) Displays “first” and throws exception

C) Nothing displayed and exception thrown

D) Other

Page 68: Puzles C#

#dotNETSpain2015

Delegates 5

B) Displays “first” and throws exception

When an exception occurs in a delegate’s function the execution is

stopped, no more functions are executed.

Page 69: Puzles C#

#dotNETSpain2015

Lambdas and closure

Func<int, int> fn = null;

for (int i = 0; i < 2; i++) {

fn += n => n + i;

}

Console.WriteLine(fn(5));

A) Displays 18

B) Displays 6

C) Displays 5

D) Other

Page 70: Puzles C#

#dotNETSpain2015

Lambdas and closure

D) Other

Displays 7

External variables are captured and used when the delegate

is executed.

Page 71: Puzles C#

#dotNETSpain2015

Interface variance

class Vehicle {... } class Car : Vehicle {...}

private static void Do1(IList<Vehicle> list) { … }

private static void Do2(IEnumerable<Vehicle> list) { … }…

var cars = new List<Car> { new Car(), new Car()};

Do1(cars);

Do2(cars);

A) Both are OK

B) Compilation error calling Do1

C) Compilation error calling Do2

D) Compilation error calling Do1 and Do2

Page 72: Puzles C#

#dotNETSpain2015

Interface variance

B) Compilation error calling Do1

Interfaces can be variant. An enumerable of cars is an

enumerable of vehicles but a list of cars is not a list of

vehicles.

Covariant: IEnumerable<out T>, IEnumerator<out T>,

IQueryable<out T>, IGrouping<out TKey, out TElement>, etc.

Contravariant: IComparer<in T>, IEqualityComparer<in T>,

IComparable<in T>, etc.

Page 73: Puzles C#

#dotNETSpain2015

Ref parameters

class A { } class B : A {}

class Uti {

public static void DoRefA(ref A a) {}

public static void DoRefB(ref B b) { }}

...

var b = new B(); Uti.DoRefA(ref b); Uti.DoRefB(ref b);

A) Both are OK

B) Compilation error in both

C) Compilation error in Uti.DoRefA call

D) Compilation error in Uti.DoRefB call

Page 74: Puzles C#

#dotNETSpain2015

Ref parameters

C) Compilation error in Uti.DoRefA call

Ref and out params must match exactly the type.

B1 b1 = new B1();

Uti.ProblemRefA(ref b1); // doesn’t compile, that’s good

...

class A { } class B1 : A {} class B2 : A {}

public static void ProblemRefA(ref A a) {

a = new B2(); // oops

}

Page 75: Puzles C#

#dotNETSpain2015

Exception 1

try { }

finally {

Console.WriteLine("start");

throw new Exception("error");

Console.WriteLine("end");

}

A) Displays “start” and “end”, no exceptions thrown

B) Displays “start”, no exceptions thrown

C) Displays “start” and throws exception

D) Other

Page 76: Puzles C#

#dotNETSpain2015

Exception 1

C) Displays “start” and throws exception

Exceptions can be thrown in a finally block.

Page 77: Puzles C#

#dotNETSpain2015

Exception 2

public void A() { try { B(); }

finally { Console.WriteLine("A finally"); } }

public void B() {

try { throw new Exception("error"); }

catch (Exception) { Console.WriteLine("B catch"); }

finally { Console.WriteLine("B finally"); } }

A) Displays “B catch”, “A finally”, “B finally”

B) Displays “B catch”, “B finally”, “A finally”

C) Displays “A finally”, “B catch”, “B finally”

D) Other

Page 78: Puzles C#

#dotNETSpain2015

Exception 2

B) Displays “B catch”, “B finally”, “A finally”

Chained finally blocks are called in reverse order.

Page 79: Puzles C#

#dotNETSpain2015

Struct default constructor

struct MyStruct {

MyStruct(int field) { _field = field; }

int _field;

public int Field { get { return _field; } }

}

MyStruct my = new MyStruct();

Console.WriteLine(my.Field);

A) Displays 0

B) Compilation error: Cannot access constructor

C) Runtime exception

D) Other

Page 80: Puzles C#

#dotNETSpain2015

Struct default constructor

A) Displays 0

Value types always have a default constructor.

Page 81: Puzles C#

#dotNETSpain2015

Redefining struct default constructor

struct MyStruct {

MyStruct() { _field = 5; }

int _field;

public int Field { get { return _field; } }

}

MyStruct my = new MyStruct();

Console.WriteLine(my.Field);

A) Displays 0

B) Compilation error

C) Displays 5

D) Other

Page 82: Puzles C#

#dotNETSpain2015

Redefining struct default constructor

B) Compilation error

Structs cannot contain explicit parameterless constructors

Page 83: Puzles C#

#dotNETSpain2015

Value type boxing

struct Point : IPoint {

public int X { get; set; }

public void ChangeX(int x) { X = x; }

public override string ToString()

{ return string.Format("X: {0}", X); }

}

interface IPoint

{

void ChangeX(int x);

}

Page 84: Puzles C#

#dotNETSpain2015

Value type boxing 1

Point p = new Point {X = 1};

object o = p;

((Point) o).ChangeX(2);

Point po = (Point) o;

Console.WriteLine(p);

Console.WriteLine(po);

A) Displays X: 1 X: 1

B) Displays X: 1 X: 2

C) Displays X: 2 X: 1

D) Displays X: 2 X: 2

struct Point : IPoint {

public int X { get; set; }

public void ChangeX(int x) { X = x; }

public override string ToString()

{ return string.Format("X: {0}", X); }

}

interface IPoint

{

void ChangeX(int x);

}

Page 85: Puzles C#

#dotNETSpain2015

Value type boxing 1

A) Displays X: 1 X: 1

Point p = new Point {X = 1};

object o = p;

((Point) o).ChangeX(2);

Point po = (Point) o;

Console.WriteLine(p);

Console.WriteLine(po);

Page 86: Puzles C#

#dotNETSpain2015

Value type boxing 2

Point p = new Point { X = 1 };

IPoint i = p;

object o = i;

i.ChangeX(2);

Console.WriteLine(i);

Console.WriteLine(o);

Console.WriteLine(p);

A) Displays X: 1 X: 1 X: 1

B) Displays X: 1 X: 2 X: 1

C) Displays X: 2 X: 1 X: 1

D) Displays X: 2 X: 2 X: 1

struct Point : IPoint {

public int X { get; set; }

public void ChangeX(int x) { X = x; }

public override string ToString()

{ return string.Format("X: {0}", X); }

}

interface IPoint

{

void ChangeX(int x);

}

Page 87: Puzles C#

#dotNETSpain2015

Value type boxing 2

D) Displays X: 2 X: 2 X: 1

Point p = new Point { X = 1 };

IPoint i = p;

object o = i;

i.ChangeX(2);

Console.WriteLine(i);

Console.WriteLine(o);

Console.WriteLine(p);

Boxing and Unboxing are only done when

necessary. An interface is the only way to modify

a boxed value type.

Page 88: Puzles C#

#dotNETSpain2015

Numerical castings

double dbl = 1.2; decimal dec = 1.2m; long lon = 1;

double lonToDbl = lon;

double decToDbl = dec;

decimal dblToDec = dbl;

A) 3 compilation errors: All conversions must be explicit

B) lonToDbl and decToDbl are OK, dblToDec must be explicit

C) All conversions are OK

D) Other

Page 89: Puzles C#

#dotNETSpain2015

Numerical castings

D) Other

lonToDbl is OK, decToDbl and dblToDec must be explicit.

C# already allows an implicit conversion from long to double, which can lose up to

twelve bits of precision.

The easy answer is: there cannot be an implicit conversion from double to decimal

because of the range discrepancy.

The conversion from decimal to double would lose far more precision; going from 96

bit precision to 52 bit precision seems like too large a drop to make this implicit.

http://ericlippert.com/2013/07/18/why-not-allow-doubledecimal-implicit-conversions/

Page 90: Puzles C#

#dotNETSpain2015

Garbage collector

private void SetTimer() {

TimerCallback callback = state => {

Console.WriteLine("called"); };

var t = new Timer(callback, null, 0, 1000); }…

SetTimer();

var m = GC.GetTotalMemory(true);

Thread.Sleep(5000);

A) Displays “called” 0 times

B) Displays “called” 1 time

C) Displays “called” more than once

D) Other

Page 91: Puzles C#

#dotNETSpain2015

Garbage collector

B) Displays “called” 1 time

Second param to Timer constructor is to start immediately.

When garbage collector is triggered, timer is collected so no more

events are triggered.

(Param true in GC.GetTotalMemory means to collect garbage before getting

total memory value)

Page 92: Puzles C#

#dotNETSpain2015

Opposite terms

Can a method be both internal and extern ?

Can a method be both dynamic and static ?

A) False False

B) False True

C) True False

D) True True

Page 93: Puzles C#

#dotNETSpain2015

Opposite terms

D) True True

[DllImport("msvcrt.dll")]

internal static extern int puts(string c);

static dynamic Hello() { return “hello”; }

Page 94: Puzles C#

#dotNETSpain2015

Leo Antoli @lantoliPuzzles C#

¡¡¡Si te ha gustado no olvides rellenar la encuesta!!!Thanks

Y

AX B