Puzles C#
-
Upload
lantoli -
Category
Technology
-
view
383 -
download
0
Transcript of Puzles C#
#dotNETSpain2015
Leo Antoli @lantoliPuzzles C#
.NET Conference 2015
Y
AX B
#dotNETSpain2015
#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
#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)
#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
#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)
#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
#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.
#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
#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.
#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
#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.
#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
#dotNETSpain2015
Overload choice 2
B) Displays T
Overload with existing methods in the class is tried before implicit casting.
#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
#dotNETSpain2015
Enum
B) Displays 0
Value types are always initialised to 0
Provide always a 0 enum element.
#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
#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
#dotNETSpain2015
Unboxing
short s = 123;
object o = s;
int i = (int)o;
A) i = 123
B) Compilation error
C) Runtime exception
D) Other
#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
#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
#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.
#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
#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
#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
#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.
#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
#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
#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
#dotNETSpain2015
Internal classes
C) Compilation error in B
Internal classes have access to private members
#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
#dotNETSpain2015
Interface member modifiers
D) Both compilation errors
All interface members are public. Modifiers can
not be used.
#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
#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.
#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
#dotNETSpain2015
Virtual methods in ctor 1
A) Displays 0
Base constructors are called first.
#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
#dotNETSpain2015
Virtual methods in ctor 2
B) Displays 5
Inline initializations are done before calling base
constructors.
#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
#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.
#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
#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.
#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
#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.
#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
#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.
#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
#dotNETSpain2015
Generics inference 1
B) Compilation error only in list2
Inference only works in generic methods.
#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
#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>();
#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
#dotNETSpain2015
Dynamic
B) Compilation or runtime error in a2,b2
RuntimeBinderException
The best overloaded methods has invalid arguments.
#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
#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)
#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
#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.
#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
#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 ;-)
#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
#dotNETSpain2015
Delegates 1
A) Displays all True
Delegates are “syntactic sugar” to create a
MulticastDelegate class.
#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
#dotNETSpain2015
Delegates 2
C) Compilation error only in predVehicle
See next puzzle...
#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
#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)
#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
#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.
#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
#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.
#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
#dotNETSpain2015
Lambdas and closure
D) Other
Displays 7
External variables are captured and used when the delegate
is executed.
#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
#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.
#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
#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
}
#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
#dotNETSpain2015
Exception 1
C) Displays “start” and throws exception
Exceptions can be thrown in a finally block.
#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
#dotNETSpain2015
Exception 2
B) Displays “B catch”, “B finally”, “A finally”
Chained finally blocks are called in reverse order.
#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
#dotNETSpain2015
Struct default constructor
A) Displays 0
Value types always have a default constructor.
#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
#dotNETSpain2015
Redefining struct default constructor
B) Compilation error
Structs cannot contain explicit parameterless constructors
#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);
}
#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);
}
#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);
#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);
}
#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.
#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
#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/
#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
#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)
#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
#dotNETSpain2015
Opposite terms
D) True True
[DllImport("msvcrt.dll")]
internal static extern int puts(string c);
static dynamic Hello() { return “hello”; }
#dotNETSpain2015
Leo Antoli @lantoliPuzzles C#
¡¡¡Si te ha gustado no olvides rellenar la encuesta!!!Thanks
Y
AX B