ottobre 2005 Blog Posts
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
Mia moglie ha ripreso a bloggare in inglese sugli argomenti a lei cari: management e project management, organizzazione e cultura aziendale, reengineering aziendale - e so che ad alcuni di voi queste cose interessano. Ha conseguito l'MBA with distinction nella migliore scuola economica olandese (NIMBAS) e fa la direttrice in un istituto di ricerca e progettazione navale (lo stesso dove io iniziai a lavorare 13 anni fa) - adesso avete capito come mai sono scappato in Italia :-)
L'indirizzo del blog è questo.
Per gli australiani essere Adrian, nel loro slang, vuol dire essere ubriaco - brutta scoperta di un sabato mattina... :-)
Ma che c'è da meravigliarsi se in questo loro slang hanno tradotto pure la Bibbia?:
"But the angel said to her, “Don’t panic, don’t chuck a wobbly. God thinks you’re okay. You’re about to become pregnant, and you’ll have a son, and you’re to call him Jesus. He will be a very big wheel, and will be called the Son of God Most High."
Disegna software e scrive codice sempre con un tocco d'aroma da gran chef. Non vedo l'ora di assaggiare il suo blog!
Ecco la soluzione rigorosamente 2.0 all'ultimo test:class Foo{ static void Main() { System.Web.Util.WorkItemCallback Main = delegate() { }; Main(); }}
Al posto di WorkItemCallback potete scegliere qualunque altro delegate pubblico del Framework che abbia la stessa dummy signature.
Anche l'altro test, quello su IsValueType, utilizza una cosa carina del 2.0. Dai, non è difficile...
Nel seguente snippet, sostituire il commento con un'unica riga di codice C# 2.0 (uno statement) così da evitare la ricorsività:
class Foo{ static void Main() { // manca in questa posizione un'unica riga di codice Main(); }}
Cosa importante, la chiamata a Main è raggiungibile e viene eseguita!
Invece di typeof(Foo).IsValueType vorrei scrivere in C# 2.0 TypeOf<Foo>.IsValueType. Implementate voi la classe TypeOf<T>, ovviamente senza utilizzare reflection.
For my non-Italian readers, if any :-) How would you implement in C# 2.0 the TypeOf<T> class, obviously without using any reflection mechanism, so that to be able to write TypeOf<Foo>.IsValueType instead of typeof(Foo).IsValueType?
Mi è venuta in mente questa idea e mi interesserebbe un feedback da parte vostra a riguardo.
Per obbligare una classe ad avere un costruttore default (public e senza parametri), mi sono costruito una marker interface generica con constructor constraint:
public interface IDefaultConstructor<T> where T : new() {}
e quindi basta che la classe Foo implementi IDefaultConstructor per essere sicuri in fase di compilazione che essa abbia un costruttore default:
class Foo : IDefaultConstructor<Foo>{ public Foo() // garantito! { // ... } // altri costruttori... public Foo(int i) { //... } // il resto dei membri}
Se in C# questo snippet:
using System;using System.Reflection; class Foo{ static void Main() { Console.WriteLine(Assembly.GetEntryAssembly().EntryPoint.Name); }}
stampa Main a console, non la stessa cosa si può dire dell'equivalente C++:
using namespace System;using namespace System::Reflection; void main(){ Console::WriteLine(Assembly::GetEntryAssembly()->EntryPoint->Name);}
che stampa a console:
main
mainCRTStartup oppure
_mainCRTStartup
in base alle opzioni:
/clr:safe
/clr:pure rispettivamente
/clr:oldSyntax (oppure /clr:initialAppDomain)
dove mainCRTStartup e _mainCRTStartup sono funzioni di C/C++ run-time startup. Il compilatore (tranne nel caso /clr:safe) chiama prima queste funzioni per le inizializzazioni necessarie alla C/C++ run-time library (variabili globali, heap, etc) e quindi saranno loro quelle decorate con .entrypoint in IL e non il metodo main dello snippet. L'opzione /clr:safe invece, produce codice verificabile e non...
Se avete bisogno di indviduare il corrispondente IL di un frammento di metodo, basta creare un block in C# per il rispettivo frammento di codice (che sarà delimitato da due nop in IL):
<method signature in C#>{ // codice... { // // zona di interesse // } // codice...}
<method signature in IL>{ // codice... nop // // zona di interesse // nop // codice...}
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.
Che bello trovare una tua conoscenza citata nel più importante libro di computer science che sia mai scritto, parlo del leggendario "The Art of Computer Programming"!
Con Gabriel Istrate partecipai quasi vent'anni fa (8 giugno 1986...) alla fase provinciale di un concorso di articoli di matematica. Lui vinse il primo premio, io il secondo. E adesso lo trovo citato dal Prof. Donald E. Knuth, vero mostro sacro dell'informatica, alla pagina 59 della bozza del pre-fascicolo 0b ("Boolean Basics") che entrerà nel volume 4A ("Enumeration and Backtracking"). Il risultato di Gabriel tratta delle clausole di Horn - incontrate sicuramente di chi ha...
Un risultato davvero sorprendente quello della legge di Benford: la probabilità che nei dati reali un numero in notazione decimale inizi con la cifra d (1<=d<=9) è:
P(d) = Log10(1+1/d)
Cosa vuol dire questo? Vuol dire che nei dati reali, la probabilità che un numero inizi con la cifra 1 è 0,301 e non 0,111 come uno si potrebbe aspettare! In più, vuol dire che è più probabile che un numero inizi con una cifra inferiore che con una maggiore! Bello, no?
Applicazioni? Per esempio nell'analisi forensica dei dati di contabilità! Se avete un datawarehose, potete verificarla.
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?)
Pochi forse sanno che il nostro amato chief software architect è anche il coautore di un davvero bellissimo risultato di combinatorica sul cosìdetto problema delle frittelle :-) (in inglese "pancake problem") insieme al vincitore del Premio Knuth per 2002 (una specie di Nobel per l'informatica teorica), il Prof. Christos H. Papadimitriou. Insieme, sono riusciti all'inizio del 1978 (Bill aveva appena compiuto 22 anni) a dimonstrare che per fare il sorting di una permutazione di ordine n ci vogliono non più di (5*n+5)/3 flip (o prefix reversal) e non meno di 17*n/16 flip. Vale la pena di scaricare (e leggere) il...
Appena ho visto la nuova XslCompiledTransform (in 2.0) è stato colpo di fulmine. E da questo esempietto fatto al volo, solo per rendere l'idea, capirete subito perché:
using System;using System.Text;using System.IO;using System.Xml;using System.Xml.Xsl; class Test{ static void Main() { string methodName = "Foo"; StringBuilder methodCode = new StringBuilder(); methodCode.AppendLine ("// ritorna la stringa Ciao ragazzi!"); methodCode.AppendFormat("public string {0}()", methodName); methodCode.AppendLine ("{"); methodCode.AppendLine (" StringBuilder sb = new StringBuilder();"); methodCode.AppendLine (" sb.Append(\"Ciao \");"); methodCode.AppendLine (" sb.Append(\"ragazzi!\");"); methodCode.AppendLine (" return sb.ToString();"); methodCode.AppendLine ("}"); Console.WriteLine(ExecuteMethodCode(methodCode.ToString(), methodName)); } static string ExecuteMethodCode(string methodCode, string methodName) { StringBuilder xsl = new StringBuilder(); StringBuilder result = new StringBuilder(); string...
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? :-)
In un'unica riga di codice C# (cioè il Main ha un'istruzione sola e non si definiscono altri membri o classi), stampate qualcosa a console senza utilizzare alcun metodo che si chiami Write o WriteLine inizi con Write.
Secondo voi, se questo snippet compila:
class Test{ static void Foo(bool b1, bool b2) { System.Console.WriteLine("{0}, {1}", b1, b2); } static void Main() { bool b1 = expr1; bool b2 = expr2; Foo(b1, b2); }}
e lasciando identiche le espressioni expr1 e expr2, dovrebbe per forza compilare senza errori anche quest'altro snippet?:
class Test{ static void Foo(bool b1, bool b2) { System.Console.WriteLine("{0}, {1}", b1, b2); } static void Main() { Foo(expr1, expr2); }}
Non sempre! Ed eccone un esempio, suggerito dalle specifiche (ECMA-334, 3rd Ed., 9.2.3 "Grammar ambiguities" - dove troverete anche altre situazioni!):
// compila senza errori e stampa True, Falseclass Test{ static void Foo(bool...
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?).