Quiz Sharp
Il seguente snippet:
using System;
interface IFoo {
IFoo GetInstance();
}
partial class Foo : IFoo {
public IFoo GetInstance() {
Console.WriteLine("Ciao");
return this;
}
}
class Program {
static void Main() {
(new Foo()).GetInstance().GetInstance();
}
}
stampa:
Ciao
Ciao
a console. Senza toccare lo snippet ma solo aggiungendone un pezzo, dobbiamo stampare a console:
Ciao
UGIdotNET
Ciao
Ieri e l'altro ieri ho tenuto un corso su Sql Server 2008 Express per 80 insegnanti di informatica arrivati per l'occasione delle Olimpiadi Nazionali di Informatica (ONI2009) che quest'anno sono state ospitate proprio dalla mia citta'. E' stata un'esperienza interessante e inedita perche' parlare di un argomento cosi' "real world" davanti alle migliori menti in ambito pre-universitario vi assicuro che non e' facile. Gente eccezionale, che vive di algoritmi, grafi e C++, un po' lontana purtroppo dalle problematiche dei DB. Ieri, cioe' nel secondo giorno, mi sono dovuto inventare la successione di Fibonacci fatta in SQL...
with fibonacci(f, g) as (
select...
Il comportamento del compilatore C#, presentato prima qui da Diego e poi nel mio post precedente, sembra singolare tra gli altri compilatori piu' conosciuti .NET. Il seguente snippet C# entra in stack overflow:
using System;
class Foo {
public virtual void Write(string s) {
Console.WriteLine("Foo virtual " + s);
}
}
class Bar : Foo {
public override void Write(string s) {
Console.WriteLine("Bar override " + s);
}
public void Write(string s, params string[] args) {
Write("Bar overload " + s);
}
}
class Program {
static void Main() {
Bar bar = new Bar();
bar.Write("Ciao!"); // Process is terminated due to StackOverflowException
}
}
mentre per gli altri linguaggi, stampa Bar override Ciao! Di seguito il codice equivalente in Visual...
Questo post di Diego Martelli, fattomi notare da un amico, riesce secondo me a sorprendere un comportamento interessante di C#, ovvero il seguente snippet di codice entra in stack overflow:
using System;
class Foo {
public virtual void Write(string s) {
Console.WriteLine("Foo virtual " + s);
}
}
class Bar : Foo {
public override void Write(string s) {
Console.WriteLine("Bar override " + s);
}
public void Write(string s, params string[] args) {
Write("Bar overload " + s);
}
}
class Program {
static void Main() {
Bar bar = new Bar();
bar.Write("Ciao!");
}
}
Probabilmente molti si aspetterebbero che venisse stampato "Bar override Ciao!" a console e invece il metodo chiamato e' il Write con l'elenco variabile di parametri...
Senza utilizzare stringhe, caratteri, numeri (literals) o file esterni, si chiede di scrivere un programma in C# 3.0 che stampi a console la definizione compilabile di un tipo non vuoto.
Scrivete una proprieta' in cui il body del getter non contenga return o throw.
Via questo post del mio connazionale Cosmin Negruseri, sono venuto a conoscenza di questa idea tanto bella quanto semplice ed efficace: proprio nella pagina Jobs di Facebook c'e' una sezione di programming puzzles belli tosti, provateli per credere. Ogni problema finisce coll'invito:
Please send your code and solutions (and a resume) to { (0xFACEB00C >> 2) in decimal format } @ facebook.com
Notate "and a resume" messo tra parentesi, per non dire dell'indirizzo email veramente originale ;) Complimenti!
(Oggi faccio gli 'anta ;) Non si scherza piu'!)
Questo snippet (di cui manca un pezzo) si esegue in Visual Studio premendo F5 e rimane fermo al breakpoint definito nel codice del metodo Main. Muovendo poi lentamente il mouse sulla finestra dello snippet in Visual Studio, si nota che a volte viene stampato uno smiley :-) a console.
class Quiz {
// da completare
static void Main() {
System.Diagnostics.Debugger.Break(); // breakpoint
}
}
Si chiede di completare il codice che manca.
Senza utilizzare alcun throw, completate il seguente snippet in tal modo che il catch stampi Ciao! a console e tutte e tre le inner exception devono essere di tipi diversi:
using System;
class Quiz {
// ... da completare
static void Main() {
try {
// ... da completare
}
catch (Exception e) {
if(e.InnerException != null && e.InnerException.InnerException != null && e.InnerException.InnerException.InnerException != null) {
Console.WriteLine("Ciao!");
}
}
}
}
Questi due snippet compilano senza errori o warning e sembrano equivalenti, ma non lo sono:
using System;
delegate Foo Foo();
class Test {
...
Una classe Foo ha un unico costruttore, pubblico e con un parametro. Puo' una classe Bar, che deriva da Foo, avere un costruttore senza parametri?
Che differenza c'e' tra (new HybridDictionary(5).Values) e (new HybridDictionary(6).Values)?
Un po' di mesi fa, Claudio Brotto, aveva proposto un simpatico quiz a cui vorrei dare adesso una soluzione (in realta' la soluzione e' per una variante leggermente modificata del quiz). Si tratta praticamente di scrivere un metodo pubblico in un assembly in tal modo che, chiamandolo da un altro assembly, questo metodo produca una stringa diversa in base al linguaggio in cui e' stato scritto l'assembly chiamante. Per esempio, questo metodo dovrebbe ritornare la stringa "C#" se chiamato da un assembly scritto in C#, oppure "Basic" se chiamato da un assembly scritto in VB.NET, etc. Piccolo vincolo della mia...
Questo snippet:
class Test{ static void Main() { try { // qui manca del codice } catch{} }}
a cui manca un pezzo di codice solo nel posto indicato dal commento, si esegue con un errore a runtime nonstante il catch generale. Che codice manca?
Che parametri dovremmo passare per chiamare il secondo metodo DoSomething (quello in rosso)? Offrite una spiegazione.
using System; class Foo{ public void DoSomething() { Console.WriteLine("()"); } public void DoSomething(params object[] args) { Console.WriteLine("(params object[])"); } public void DoSomething(object arg, params object[] args) { Console.WriteLine("(object, params object[])"); }}
La soluzione al Quiz Sharp #61 mi sembra abbastanza interessante per meritare un post a parte (nomi come Miguel de Icaza, Jon Skeet, Abhinaba Basu, hanno considerato strano il comportamento del compilatore C# 2.0 nel comparare i valori value type a null)
La risposta corretta al quiz e' che eseguendo lo snippet si ottiene un'eccezione a runtime (StackOverflowException). Vediamo di seguito il perche', con le specifiche in mano:
Per evaluare l'espressione value != null nell'implementazione dell'operatore, dove value e' un not-nullable value type, il compilatore applica alcune conversioni. Per esempio, per ogni nullable type, esiste una conversione implicita dal tipo null al...
Di seguito un quiz a quattro mani con Matteo Spreafico, risultato di un bellissimo e lunghissimo chat:
Cosa stampa a video questo snippet?
struct Foo{ public static implicit operator bool(Foo value) { return value != null; }}class Test{ static void Main() { if (new Foo()) { System.Console.WriteLine("Ciao"); } }}
1. niente
2. Ciao
3. non compila
4. runtime exception
Definite un tipo per foo (e che non sia un nullable type) in tal modo che il seguente snippet:
foo = null;System.Console.WriteLine(foo.ToString()); si esegui senza errori.
Si chiede di completare il pezzo di codice che manca nel seguente snippet C# 2.0 nel posto marcato dal commento dei tre punti di domanda, in tal modo che il programma stampi 2007 a console:
using System;class QuizSharp{ // ??? static void Main() { Console.WriteLine(sum(1967)(40)); }}
Piccolo aiuto: sto preparando per domani la lezione sui delegate ;-)
Scrivete una classe Foo, che derivi direttamente da System.Object e che non sovvrascrivi il metodo System.Object.ToString, in tal modo che il seguente snippet:
Foo foo = new Foo();System.Console.WriteLine(foo);
stampi solo "Ciao" a console.
[OT] Oggi e' gia' il terzo giorno di corso .NET che devo tenere ogni mattina per quattro mesi di fila davanti ad una classe di 10 persone a 300 metri da casa mia in Romania. Magari ne uscira' fuori anche un piccolo user group piu' in la', vedremo - il terreno e' assolutamente vergine e la nuova esperienza si mostra per adesso abbastanza interessante.
Troppo banale anche questo quiz? :-)
Possibile avere istanze di Foo? Tempo massimo di risposta: 30 secondi.
class Foo { public Foo(ref Foo arg) { arg = this; } }
Potrebbe andare bene per un colloquio (lo so che è semplice ma sono curioso cos'avreste risposto in 30 secondi).
Cosa stampa a console il seguente snippet e perché?:
using
System;
class
Foo
{
public
Foo(out Foo foo)
{
foo =
this;
throw
new Exception();
}
}
class
Test
{
static
void Main()
{
Foo
f = null;
try
{ f = new Foo(out
f); }
catch
{ }
Console.WriteLine(f
== null ? "null"
: "not null");
}
}
Vi incito a comprare il recente libro di Joe Duffy semplicemente copiando dalla pagina 24 queste due righe di codice:
int? x = 10;Console.WriteLine(x.GetType());
Cosa stampa a console e perché?:
A. System.Int32
B. System.Nullable`1[System.Int32]
Se IFoo non è un'interfaccia marker, cioè non è vuota, quante soluzioni possibili esistono perché il seguente snippet
class Foo : IFoo { }
compili in C# senza errori?
A. 0
B. 6
C. 15
Guardate con attenzione questo screenshot preso dal sito di una persona che lavora in Microsoft (no, davvero):
La domanda del quiz è cosa stava facendo più probabilmente il tizio:
A. stava per compilare la classe String, oppure
B. guardava del codice "riflesso" del Framework?
Ovviamente, argomentate la risposta.
P.S.: Ho cancellato con la striscia grigia un pezzo poco importante per la risposta.
La risposta corretta al Quiz #52 l'ha data Francesco. Vi faccio però ancora un paio di domande:
è possibile modificare il codice C# per renderlo equivalente a quello VB .NET? (e se sì, come?)
è possibile modificare il codice VB .NET per renderlo equivalente a quello C#? (e se sì, come?)
Sono contento di trovare il mio lontano primo quiz (ormai è passato quasi un anno e mezzo) linkato da un ancora più lontano ragazzo peruviano. Ciao Alexander!
Ragazzi, faciamo la prossima cena UGI a Urubamba? :-)
Imports System Class Foo Public Sub New() Console.WriteLine("Foo") End SubEnd Class Class TestBase Public Sub New() Console.WriteLine("Base") End SubEnd Class Class Test : Inherits TestBase Dim f As Foo = New Foo()End Class
using System; class Foo { public Foo() { Console.WriteLine("Foo"); }} class TestBase { public TestBase() { Console.WriteLine("Base"); }} class Test : TestBase { Foo f = new Foo();}
Questi due snippet sembrano gemelli... E perché non lo sono?
P.S.: Non è a risposta multipla come gli altri quiz - ho fatto un'eccezione perché non mi pare che c'entri con gli altri test (agli ultimi due non avete ancora risposto! troppo strani?).
Sono rimasto un po' male quando ho scoperto che è già uscito questo libro (il 24 di giugno):
J. Bloch, N. Gafter, "Java Puzzlers: Traps, Pitfalls, and Corner Cases", Addison-Wesley Professional (2005)
visto che, questa primavera mi è stata rifiutata una proposta identica da un editore con la motivazione: un libro di quiz bastardi? no, non si venderebbe...
A voi dice qualcosa questo elenco?
"reveals oddities of the Java programming language through entertaining and thought-provoking programming puzzles"
"I laughed, I cried, I threw up (my hands in admiration)"
"dive deep into the subtleties of the Java programming language and its core libraries"
"95 diabolical...
Il seguente snippet, quante volte stampa Ciao a console, e perché?
using System; class Foo{ public Foo() { Console.WriteLine(this); } public static Foo MyField = new Ciao();} class Ciao: Foo{ public static Foo MyProperty { get { return new Ciao(); } }} class Test{ static void Main() { Console.WriteLine(Ciao.MyProperty); }}
A. 1
B. 2
C. 3
D. StackOverflowException
Troppo semplice, basta un po' di attenzione...
Quale tra i seguenti due metodi ricorsivi riuscirà a fare più iterazioni e perché?
void Foo(){ System.Reflection.MethodBase.GetCurrentMethod().Invoke(this, null);}void Bar(){ Bar();}
A. Foo;
B. Bar;
C. per Foo non otteniamo StackOverflowException.
I seguenti due snippet si compilano con le stesse opzioni, però il codice IL generato per i due foreach, come struttura, è ben diverso:
using System;using System.Management;class Foo{ static void Main() { foreach (ManagementObject device in new ManagementClass("Win32_LogicalDisk").GetInstances()) { Console.WriteLine(device["deviceid"]); } }}
using System;using System.Xml;using System.Xml.Schema;class Foo{ static void Main() { string xsd = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + "\\Microsoft Visual Studio .NET 2003\\Common7\\Packages\\schemas\\xml\\asp.xsd"; XmlTextReader reader = new XmlTextReader(xsd); foreach(XmlSchemaObject schemaObj in XmlSchema.Read(reader, null).Items) { Console.WriteLine(schemaObj.LineNumber); } reader.Close(); }}
Offrite una spiegazione.
using System;using System.Diagnostics;class Foo{ [Conditional("X")] static void Main() { Main(); Console.WriteLine("Ciao!"); }}
Vi aspettate:
A. stampa Ciao! a console
B. non stampa niente
C. errore StackOverflowException a runtime
Le vostre risposte con le dovute spiegazioni lasciatele nei commenti, fino a mercoledì sera.
Nell'ultimo quiz (#47) è stato l'array initializer:
int[] a = new int[3]{1, 2, 3};
a generare la classe '<PrivateImplementationDetails>' di cui proverò a parlere in questo post.
Cioè, cambiando l'array initializer con:
int[] a = new int[3];a[0] = 1;a[1] = 2;a[2] = 3;
lo snippet del quiz avrebbe stampato a console abc (la risposta B e non C).
Nel nostro caso, il codice IL generato per questa classe non documentata è:
.class private auto ansi '<PrivateImplementationDetails>' extends [mscorlib]System.Object{ .class explicit ansi sealed nested private '$$struct0x6000001-1' extends [mscorlib]System.ValueType { .pack 1 .size 12 } .field static assembly valuetype '<PrivateImplementationDetails>'/'$$struct0x6000001-1' '$$method0x6000001-1' at D_00002050}.data D_00002050 = bytearray (01...
using System;using System.Reflection;class Foo{ public Foo() { int[] a = new int[3]{1, 2, 3}; foreach(int i in a) { Console.Write(i); } Console.WriteLine(); } static void Main() { try { Activator.CreateInstance(Assembly.GetExecutingAssembly().GetTypes()[2]); } catch(IndexOutOfRangeException e) { Console.WriteLine("abc"); } }}
Cosa stampa a console e perché?
A. 123
B. abc
C. non viene stampato nulla
La frase del giorno: "due anni in Garabagna, circa altrettanti nel paese della Magia, un po' meno a Poddema" - Henri Michaux
Questo codice, sintatticamente corretto, compila?
class Foo{ static byte GetMaxByte() { return System.Byte.MaxValue; }}
Dipende:
A. dalla versione del framework;
B. dal linguaggio;
C. dal produttore del compilatore C#.
(Aggiornamento 01/03/05): aggiunto sintatticamente corretto - grazie M.rkino
using System;
class MyNullReferenceException: NullReferenceException
{
public override
string Message
{
get{return
"Ciao!";}
}
}
class Foo
{
static void
Main()
{
try
{
throw null
as
MyNullReferenceException;
}
catch(MyNullReferenceException
e)
{
Console.WriteLine(e.Message);
}
catch(NullReferenceException
e)
{
Console.WriteLine(e.Message);
}
}
}
Cosa viene visualizzato a console e perché?
A. Object reference not set to an instance of an object.
B. Ciao!
C. non compila
D. errore a run-time
using System;using System.Threading;class Foo{ static void Main() { try { try { try { Thread.CurrentThread.Abort(); } catch { Console.Write(1); } finally { Thread.ResetAbort(); } } catch { Console.Write(2); } } catch { Console.Write(3); } }}
Cosa viene visualizzato a console e perché?
A. niente
B. errore a run-time
C. 1
D. 12
E. 123
Lasciate le vostre risposte, come al solito, nei commenti.
Il quiz è apparso in variante ovviamente C++ alla pagina 830 nel suo ormai dimenticato libro "Programming Applications for Microsoft Windows"
int FuncaDoodleDoo(){ int temp = 0; while(temp < 10) { try { if(temp == 2) continue; if(temp == 3) break; } finally { temp++; } temp++; } temp += 10; return temp;}
e chiede: "Can you determine what the following function returns?".
Mi raccomando, nei commenti non rispondete solo con sì e no :-)
using System;namespace Quiz.System{ class Foo { static void Main() { Console.WriteLine("Ciao!"); } }}
namespace Quiz.System{ using System; class Foo { static void Main() { Console.WriteLine("Ciao!"); } }}
Chi votereste? Destra o sinistra? E perché?
Chi ha seguito la mia sessione al workshop del 2 dicembre già lo conosce. Per gli altri, qui sotto, una domandina:
Cosa producono i seguenti due pezzi di codice?
C#
Visual Basic .NET
[IndexerName("P")] public string this[int i] { get { return _p[i]; } set { _p[i] = value; } }
<IndexerName("P")> _ Public Property Item(ByVal i As Integer) As String Get Return _p(i) End Get Set(ByVal Value As Integer) _p(i) = Value End Set End Property
protected internal in C# (o Protected Friend in Visual Basic .NET) corrisponde in CTS a:
A. Family-Or-Assembly, oppure a
B. Family-And-Assembly?
Oltre alla vostra risposta esatta, sarei interessato a sentire anche i vostri commenti personali sulla scelta logica del significato da parte degli architetti del CLR.
using System;class Bar: Attribute{ static Bar() { Foo.WriteNumberOfCustomAttributes(); } public Bar() { Console.Write("Bar "); }}[Bar]class Foo{ public static void WriteNumberOfCustomAttributes() { Console.Write(typeof(Foo).GetCustomAttributes(false).Length + " "); } static void Main() { WriteNumberOfCustomAttributes(); Console.Read(); }}
Cosa viene visualizzato a console?
A. 1
B. 1 1
C. 1 Bar 1
D. 1 Bar 1 Bar
E. Bar 1 Bar 1
E perché?
Se i miei quiz non vi bastano, potete provare quelli di Brad (ma questo senz'altro lo sapete) oppure il concorso mensile di Wintellect: "Who Wants to Be a Wintellectual?" (si vince un libro).
A quelli potenti e insoddisfatti anche dopo questo :-) magari il concorso mensile "Ponder This" fatto da IBM Research dovrebbe dire qualcosa. Una lista lunga di rumeni che hanno risposto correttamente a "Ponder This" l'ho compilata un po' di tempo fa in un commento a questo post di Adi Oltean, anche lui rumeno.
Oppure, potete partecipare alla TopCoder Competition, dove i rumeni sono all'ottava posizione.
Supponiamo che vi troviate davanti a un quiz come questo:
class Foo{ static void Main() { string s1 = string.Empty; string s2 = ""; double d = System.Math.PI; }}
Secondo voi, quanti warning "The variable 'variable' is assigned but its value is never used" otterreste in compilazione? Qualcuno dirà 3, un altro 2, un altro ancora 1, mentre i più fighi diranno nessuno. La risposta però è 2. Per capire il motivo non mi sono stati d'aiuto né le specifiche, nè Richter, né Box, né Gunnerson. La risposta l'ho trovata spulciando nel Rotor, nel corpo dei metodi FUNCBREC::reportUnreferencedVars (le righe 668-683) e FUNCBREC::bindAssignment (le righe 7488-7533). Vediamo cosa...
using System;class Outer{ class Inner { static void Main() { Console.WriteLine("Inner"); Console.Read(); } } static void Main() { Console.WriteLine("Outer"); Console.Read(); }}
Vi aspettate che:
A. scriva Inner a console;
B. scriva Outer a console;
C. non compili;
D. abbia fatto 200 post :-)
Ci vediamo domani ragazzi!
La canzone del giorno: Nick Cave & The Bad Seeds - "Babe, You Turn Me On" in cui dice:
Everything is collapsing, dearAll moral sense has goneIt's just history repeating itselfAnd babe, you turn me on
Quante volte questo metodo scrive "Ciao" a console?
static void Foo(bool p){ for(bool b = p; b = p; b = p) { Console.WriteLine("Ciao"); }}
A. l'esecuzione di questo metodo non scrive niente a console;
B. abbiamo un ciclo infinito;
C. non scrive nulla oppure ciclo infinito in funzione del parametro p;D. una volta.
Potete lasciare le vostre risposte nei commenti.
I numeri possibili nel Quiz Sharp #36 sono:
1 - Pow(10, -2043)
e
0 = 0 * Pow(10, Pow(10, 2043) - 1)
Per avere un'idea sulla grandezza del numero moltiplicato con 0, pensate che un googolplex è "solo" Pow(10, Pow(10, 100)).
Se al posto di 0 mettete 1, cioè 1e99...9, ovviamente il compilatore vi dà "Floating-point constant is outside the range of type 'double'". Come mai allora per 0e99...9 va tutto bene e il compilatore fornisce il risultato corretto? Il compilatore riconosce una moltiplicazione con 0 e chiude per il resto gli occhi. Quando tokenizza la parte exponent dell'espressione 0e99...9, non gli interessa di rappresentare...
Se dobbiamo sostituire il punto di domanda con un unico carattere, quante soluzioni valide (senza errori o warning) esistono? (in quella riga si trovano 2043 cifre 9 consecutive)
class Foo{ static void Main() { System.Console.WriteLine (0?99...9 ); }}
A. 1;
B. 2;
C. 3.
Potete lasciare le vostre risposte nei commenti.
using System;using System.Collections;class Foo{ static void Main() { Hashtable table = new Hashtable(); int intKey = 50; long longKey = 50; table.Add(intKey, "SomeValue"); table.Add(longKey, "SomeValue"); Console.WriteLine(table.Count); Console.Read(); }}
Cosa viene visualizzato a console?
A. 1
B. 2
C. errore a run-time: System.ArgumentException, Item has already been added. Key in dictionary: "50" Key being added: "50"
using System;class Test{ static void DoIt(int a, long b, long c) { Console.WriteLine("In DoIt(int, long, long)"); } static void DoIt(int a, int b, long c) { Console.WriteLine("In DoIt(int, int, long)"); } static void Main() { DoIt(1, 2, 3); Console.Read(); }}
What is the result of compiling and executing the above code?
A. Prints "In DoIt(int, long, long)"
B. Prints "In DoIt(int, int, long)"
C. Compiler Error
D. Run-Time Error
In Java si ottiene lo stesso risultato - guardate solo dopo aver pensato ad una risposta :-)
Che valore ha la seguente espressione?
System.Convert.ToBase64String(new byte[3]).TrimEnd('=').Split('A').Length
A. 3
B. 4
C. 5
using System;class A{ public virtual void M(int i) { Console.WriteLine("A::M(int) called"); }}class B: A{ public override void M(int i) { Console.WriteLine("B::M(int) called"); } public void M(long i) { Console.WriteLine("B::M(long) called"); }}class Test{ static void Main() { B b = new B(); int i = 0; b.M(i); }}
Cosa viene visualizzato a console? Qui non abbiamo C ma non vuol per niente dire che sia più semplice! :-)
A. B::M(long) called
B. B::M(int) called
using System;class Test{ static void Main() { int i; try { goto lab; } finally { i = 3; } lab: Console.WriteLine("i = {0}", i); }}
Vi aspettate:
A. Dipende dalla versione del Framework
B. i = 3
C. Errore di compilazione ("Use of unassigned local variable 'i'")
using System;class A{ public int x; static A(){}}class Test{ static void Main() { A a = null; int i = 0; a.x = a.x + 1/i; }}
Vi aspettate:
A. System.NullReferenceException
B. System.DivideByZeroException
C. Errore di compilazione ("Division by constant zero")
Un assolutamente fantastico articolo del mio connazionale Nicu Georgian Fruja, Research Assistant all'Institute of Theoretical Computer Science, ETH Zurigo, purtroppo a pagamento (costa 15$):
N.G. Fruja, "Specification and Implementation Problems for C#", Lecture Notes in Computer Science, Volume 3052 (2004), pp. 127 - 143
Per darvi un assaggio di questa meraviglia, ecco il link per le 9 pagine free dell'appendice che comprendono 17 quiz tostissimi! Perché ne parlo così entusiasta? Un frammento dell'abstract:
"[...] We tried to directly and faithfully reflect the intuitions and design decisions which are expressed in the C# Language Specification. This work [...] brought to light a few gaps...
"adrianflorea lives here or, at least, his quizzes do". Ne ho postati solo i primi 3 dei 29 che sono riuscito finora ad immaginare - tanto per vedere come funziona Quizilla. Un po' bruttino, però comodo :-)
"The 'l' suffix is easily confused with the digit '1' -- use 'L' for clarity". Grazie a questo warning "premuroso" del compilatore C#, il seguente quiz in Java preso dalla stessa Session TS-2575 di 2004 JavaOne Conference non ha tanto senso in C#:
6. "It's Elementary"
public class Elementary{ public static void main(String[] args) { System.out.println(54321 + 5432l); }}
What Does It Print?
A. -22430
B. 59753
C. 10864
D. 108642Program doesn’t say what you think it does!
Another Look
public class Elementary{ public static void main(String[] args) { System.out.println(54321 + 5432l); }}
1 - the numeral one
l - the lowercase letter el
How Do You Fix It?
We won’t insult your intelligence
The Moral
Always...
Appena premuto il bottone "Inserici" per il post precedente, scopro un altro quiz (sempre della Session TS-2575 di 2004 JavaOne Conference presentata da Joshua Bloch e Neal Gafter) irriproducibile in C#: "5. Shades of Gray" (per essere precisi, l'autore in realtà è Dominik Gruntz e il quiz appare per la prima volta un anno e mezzo fa su Journal of Object Technology in un articolo interessante, intitolato "C# and Java: The Smart Distinctions").
Si tratta di un'altra "feature" di Java: "Java makes a distinction between the namespace of fields, methods and nested classes within a class, i.e., it is possible to...
Mi sono scaricato i 151 MB di PDF della "2004 JavaOne Conference" e ne stavo facendo un giro veloce quando ho trovato... che cosa? ...una session fatta solo di quiz :-)
J. Bloch, N. Gafter, "Still More Programming Puzzlers", Session TS-2575, 2004 JavaOne Conference
Il bello è che uno di questi quiz "4. More of the Same", è irriproducibile in C#! :-) Come mai? Perchè il quiz in questione sfrutta una "feature" di Java secondo la quale "It is possible for a method to have the same name as a constructor" ma, consigliano gli autori, "Don't ever do it". C# è nato...
Incuriosito da questo frammento dal libro di Box & Sells (l'edizione italiana, p. 119):
"L'attributo [System.Flags] influenza anche l'implementazione di ToString in modo che la rappresentazione in stringa del valore sarà una lista separata da virgole dei nomi dei membri anziché del singolo membro.",
ho giocato un po'. Per esempio, questo snippet:
using System;class Foo{ [Flags] enum NaN { Non = 1, un = 2, numero = 4, reale = 8 } static void Main() { NaN f = NaN.Non | NaN.un | NaN.numero | NaN.reale; Console.WriteLine(double.NaN.ToString(new System.Globalization.CultureInfo("it-IT"))); Console.WriteLine(f.ToString().Replace(",", string.Empty)); Console.Read(); }}
stampa a video:
Non un numero realeNon un numero reale
Un esempio meno folle :-) lo trovate nella documentazione di System.FlagsAttribute.Continuando a giocare, sono partito da questo snippet:
using System;class...
Questo prendetelo come relax, così sbaglierete di sicuro :-)
Una divisione tra due variabili int, quante eccezioni può generare:
A. 1
B. 2
C. dipende dal contesto checked o unchecked
using System;struct Foo{ public double Value; public Foo(double d) { Value = Double(d); } private double Double(double d) { return 2 * d; }}class Test{ static void Main() { Foo f = new Foo(1); Console.WriteLine(f.Value); Console.Read(); }}
Quale tra le seguenti parole chiave si deve aggiungere al codice qui sopra per renderlo compilabile senza errori:
A. static (per avere: private static double Double(double d))
B. new (per avere: Value = new Double(d);)
C. this (per avere: Value = this.Double(d);)
A parte il fatto che ha risposto correttamente all'ultimo quiz :-) Gianluca, attento come sempre, mi ha fatto notare nel libro di Box & Sells un esempio in qualche modo simile al mio, ma molto più incasinato. Lo trovate nell'edizione italiana alla pagina 171, listato 6.6 "Abuso dell'ereditarietà".
using System;class Foo1{ public override string ToString() { return "Foo1"; }}class Foo2: Foo1{ private new string ToString() { return "Foo2"; }}class Foo3: Foo2{ public override string ToString() { return base.ToString(); }}class Foo{ static void Main() { Console.WriteLine(new Foo3().ToString()); Console.Read(); }}
Cosa viene visualizzato a console?
A. Foo1
B. Foo2
C. Questo è il mio 100° post! :-)
D. non compila ('Foo2.ToString()' is inaccessible due to its protection level)
Ispirato da un esempio di Steven John Metsker ("Design Patterns in C#", p. 158, 382)
class FooBase{ string _name; FooBase(string name) { _name = name; }}class Foo: FooBase{}
Vi aspettate:
A. compila senza warning o errori
B. compila con warning
C. non compila (errore di compilazione)
class Foo{ const object refTypeConst = null; const System.DateTime valTypeConst = System.DateTime.MinValue;}
Vi aspettate:
A. compila senza errori
B. errore di compilazione sulla dichiarazione della refTypeConst
C. errore di compilazione sulla dichiarazione della valTypeConst
using System;class Bar{ static int i = 0; class Foo { public Foo() { i++; } static Foo() { i--; } } static void Main() { Foo f1 = new Foo(); Foo f2 = new Foo(); Console.WriteLine(i); Console.Read(); }}
Cosa viene visualizzato a console?
A. 0
B. 1
C. 2
Un quiz simpatico, di Clive Tooth:
Would this class declaration compile?
class Class{ delegate Delegate Delegate(Delegate Delegate); static Delegate Static(Delegate Static) { return Static; }}
class Foo{ int P { get { return 1; } } string get_P() { return "1"; }}
Vi aspettate:
A. errore sulla proprietà
B. errore sul metodo
C. compila senza errori
using System;class Foo{ static void Main() { string s; int i = 1; s = i == 1 ? "A" : s + "B"; Console.WriteLine(s); Console.Read(); }}
Cosa viene visualizzato a console?
A. A
B. compila con warning
C. non compila
using System;class Foo{ static Foo() { Console.WriteLine(i); } static int i = 1; static void Main() { Console.Read(); }}
Cosa viene visualizzato a console?
A. 0
B. 1
C. non viene visualizzato nulla.
using System;struct A{}struct B{ public A A;}struct C{ public A A; public int I;}class Foo{ static unsafe void Main() { Console.WriteLine("A:{0} B:{1} C:{2}", sizeof(A), sizeof(B), sizeof(C)); Console.Read(); }}
Si compila con "Allow Unsafe Code Blocks = True" se utilizzate VS, oppure "/unsafe" da linea di comando (csc)
Cosa viene visualizzato a console?
A. 1 1 8
B. 1 2 5
C. 0 0 4
Visti i feedback abbastanza buoni :-) della serie di quiz su C#, ho pensato ad aprirne un'altra, forse più difficile, su design patterns. L'ho chiamata Patty Quiz per toglierle un po' di occhiaie e non per ultimo, perché mi piace tanto Patty Pravo :-)
Il codice qui sotto vuole calcolare il numero delle foglie (nodi senza figli) del grafo orientato determinato dal nodo di partenza root:
using System;using System.Collections;interface Component{ void Add(Component c); int Count{get;}}class Composite: Component{ private ArrayList _children = new ArrayList(); public void Add(Component c) { _children.Add(c); } public int Count { get { int count = 0; foreach(Component c in _children) { count += c.Count; } return count; } }}class Leaf: Component{ public void Add(Component c) { throw new NotSupportedException("Le foglie non hanno...
Cambiate nel Quiz Sharp 17 il tipo Weird da struct a class.
Cosa viene visualizzato adesso a console?
A.21
B.22
C.24
Già sento un "mumble" di qualcuno :-)
Questo quiz è ispirato da un bellissimo post di Cyrus Najmabadi (C# IDE Team) - che solo a maggio ha postato nel suo blog per 73 volte! :-)
using System;class C1{ public static void M(Weird w) { w.ToString(); Console.WriteLine(w.ToString()); }}class C2{ public static void M(Weird w) { NewMethod(w); Console.WriteLine(w.ToString()); } private static void NewMethod(Weird w) { w.ToString(); }}struct Weird{ private int _i; public Weird(int i) { _i = i; } public override string ToString() { _i++; return _i.ToString(); }}class Foo{ static void Main() { Weird w = new Weird(0); C1.M(w); C2.M(w); Console.Read(); }}
Cosa viene visualizzato a console?
A.21
B.22
C.24
Questo è un po' troppo semplice, ma lo posto lo stesso :-)
using System;class Foo{ static void Main() { Console.WriteLine(Convert.ToBoolean(Convert.ToInt32(Convert.ToChar(Convert.ToInt32(false))))); Console.WriteLine(Convert.ToBoolean(Convert.ToInt32(Convert.ToChar(Convert.ToInt32(false).ToString())))); Console.Read(); }}
Cosa viene visualizzato a console?
A.FalseFalse
B.FalseTrue
C.TrueFalse
Tanti dei metodi della classe System.Convert sono riservati per un utilizzo futuro.
using System;enum Foo{ A, B = A - 1, C}class Bar{ static void Main() { Console.WriteLine(Foo.C); Console.Read(); }}
Cosa viene visualizzato a console?
A. A
B. 0
C. C
using System;enum Numero{ Uno = 1, Due, Tre, Quattro, Cinque}class Foo{ static void Main() { Console.WriteLine((Numero)(Numero.Cinque - Numero.Tre)); Console.Read(); }}
Cosa viene visualizzato a console?
A. Numero.Due
B. Due
C. 2
Responsabile per il loop infinito notato qui da M.rkino:
for(int i = int.MinValue; i <= int.MaxValue; i++){ Console.Write(".");}
è questa "identità": MaxValue + 1 = MinValue cioè, all'ultimo i++ il valore della i da MaxValue ridiventa MinValue.
using System;class Foo{ static void Main() { int j = 0; for(int i = int.MinValue; i < int.MaxValue; i++) { if(i == -i) { j++; } } Console.WriteLine(j); Console.Read(); }}
Cosa viene visualizzato a console?
A. 2
B. 1
C. 0
Siete sicuri? :-)
using System;class Base{ public Base() { Method(); } public virtual void Method() { Console.WriteLine("I'm the Base"); }}class Derived: Base{ public Derived() { Method(); } public override void Method() { Console.WriteLine("I'm the Derived"); }}class Foo{ static void Main() { Derived d = new Derived(); d.Method(); Console.Read(); }}
Cosa viene visualizzato a console?
A.I'm the DerivedI'm the Derived
B.I'm the DerivedI'm the DerivedI'm the Derived
C.I'm the BaseI'm the DerivedI'm the Derived
Il quiz è ispirato da questo post di Stephen Dunn (da leggere anche tutti i "Next in topic"), post a sua volta ispirato da questa regola FxCop.
Adesso che avete giocato col quiz di Gianluca, vediamo se è rimasta qualche sorpresa sul fondo del sacco :-)
using System;class Foo{ static void Main() { Console.WriteLine(Test()); Console.Read(); } static int Test() { int i; try { i = 1; return i; } finally { i = 2; } i = 3; return i; }}
Vi aspettate:
A. 1
B. 2
C. 3
Un quiz bellissimo, firmato Brad Abrams:
Will this code throw an ArgumentNullException? and why?string firstName = null;String.Format (“{0}”, firstName);
Non cliccate qui prima di dare la risposta :-)
using System;class Foo{ static void Main() { int i, j; i = j = 0; i += i = 1 * i++; j += j = 1 * ++j; Console.WriteLine("{0} {1}", i, j); Console.ReadLine(); }}
Vi aspettate:
A. 1 1
B. 1 0
C. 0 1
using System;class Foo{ public static bool operator true(Foo f) { return false; } public static bool operator false(Foo f) { return true; }}class Bar{ static void Main() { if(new Foo()) { Console.WriteLine("Hello world!"); } else { Console.WriteLine("Ciao mondo!"); } Console.ReadLine(); }}
Vi aspettate:
A. non compila
B. Hello world!
C. Ciao mondo!
using System;class Foo{ static void Main() { Random r1 = new Random(); Random r2 = new Random(); Console.WriteLine(r1.Next() == r2.Next()); Console.WriteLine(r1.Next(r1.Next()) == r2.Next(r2.Next())); Console.WriteLine(r1.Next(r2.Next()) == r2.Next(r1.Next())); Console.ReadLine(); }}
Vi aspettate:
A.FalseFalseFalse
B.TrueFalseFalse
C.TrueTrueFalse
D.TrueTrueTrue
using System;using System.Reflection;class _1E{ class _1 { }}class _1F{ static void Main() { foreach(Type t in Assembly.GetExecutingAssembly().GetTypes()) { foreach(MemberInfo m in t.GetMembers(BindingFlags.NonPublic)) { if(m.MemberType == MemberTypes.NestedType) { Console.WriteLine(double.Parse(((Type)m).FullName.Replace("_", ""))); } } } Console.ReadLine(); }}
Cosa scrive sulla console? :-)
using System;class Foo{ static void Main(ref string[] args) { Console.WriteLine("Hello World of ref!"); Console.ReadLine(); } static void Main(string[] args) { Console.WriteLine("Hello World!"); Console.ReadLine(); }}
A. non compila
B. compila con warning
C. compila senza warning
A proposito del mondo dei ref, approfitto per passare questo consiglio di Brad Abrams (SLAR, p. 304):"In general by reference parameters make the APIs much harder to use and should be avoided in good library design"Chiaro che il "good library design" non c'entra nulla col "good quiz design" :-)
using System;enum Bar{ Baz}class Foo{ static void Main() { Bar b1 = (Bar)1; Bar b2 = 0; Console.WriteLine("{0} {1}", b1, b2); Console.ReadLine(); }}
Vi aspettate:
A. 1 0
B. errore
C. 1 Baz
Qui un po' di storia su Foo, Bar, Baz, Qux, Quux, Quuux, Quuuux, etc. :-)
using System;class M{ static void Main() { int i = 1; double d; try { d = 1.0/0; i = 2; d = 1/0.0; i = 3; d = 1/String.Empty.Length; } catch(DivideByZeroException e) { Console.WriteLine(i); } Console.ReadLine(); }}
Cosa scrive sulla console?
A. 1;
B. 2;
C. 3.
P.S.: l'iniziale della classe, M, è per M.rkino - sa lui perché :-)
Bello il quiz di Andrea! Questo è il mio :-)
class Q1: System.NullReferenceException{ static int Main() { try { return 0 + (Q1)null; } catch(Q1 q) { throw; } } public static int operator +(int i, Q1 q) { return i + q.Message.Length; }}
Si ottiene:
A. NullReferenceException;
B. Q1;
C. StackOverflowException.