marzo 2005 Blog Posts
Il seguente snippet è preso dal paragrafo 9.6.2 delle specifiche VB .NET:
Imports SystemClass Raiser Public Event Constructed() Public Sub New() RaiseEvent Constructed() End SubEnd ClassModule Test Private WithEvents x As Raiser Private Sub HandleConstructed() Handles x.Constructed Console.WriteLine("Constructed") End Sub Public Sub Main() x = New Raiser End SubEnd Module
Non mi spiego come un errore così elementare (vedi la Reference: "Non-shared events should not be raised within the constructor of the class in which they are declared. Although such events do not cause runtime errors, they may fail to be caught by associated event handlers") possa essere fatto proprio da...
In Visual Basic .NET, la keyword GetType è più vicina alla BCL rispetto alla keyword corrispondente typeof in C#. Questa vicinanza però, non deve creare confusione tra keyword e metodo. Mi spiego con un esempio tipo quiz :-)
Supponiamo di avere questi due file in Visual Basic .NET, Foo.vb:
' Foo.vbPublic Class Foo : End Class
e Test.vb:
' Test.vbImports SystemClass Test Shared Sub Main() Console.WriteLine(Type.GetType(GetType(Foo).FullName)) End SubEnd Class
che compilano senza errori. Il risultato dell'esecuzione di Test però, dipende dalle "compiler option" con cui li abbiamo compilati:
se compiliamo con:
vbc test.vb foo.vboppure con:vbc /t:module foo.vbvbc /addmodule:foo.netmodule test.vbl'esecuzione di Test stampa Foo a console;
se...
Avere in un linguaggio .NET un metodo pubblico, non statico, conforme al CLS e di una classe pubblica, in un assembly, non necessariamente vuol dire che possa essere richiamato da un altro assembly!
L'esempio non è evidente: il metodo toString in questo snippet J#:
class A extends java.lang.Object{ public String toString() { return "A::toString"; }}
non può essere richiamato da C#:
class Test{ static void Main() { // error CS0117: 'A' does not contain a definition for 'toString' System.Console.WriteLine(new A().toString()); }}
se non lo sostituiamo con ToString. Da VisualBasic .NET invece, va ("identifiers are case insensitive"):
Class Test Shared Sub Main() ' OK ...
In modo sorprendente, la soluzione al test è questa: compilate il seguente snippet J#:
public class a{ public int GetHashCode() { return 15; }}
e referenziate l'assembly al vostro snippet C#:
class Test{ static void Main() { System.Console.WriteLine(new a()); }}
Come mai stampa a@f a console? Semplice! In Visual J# tutte le classi sovrascrivono implicitamente i metodi virtual MemberwiseClone() e ToString(), dove ToString() semplicemente ritorna com.ms.vjsharp.lang.ObjectImpl.jloToString(this) (dell'assembly vjslib.dll). E che stringa ritorna questo metodo jloToString?:
new StringBuilder(obj.GetType().FullName.Replace('+', '$')).Append('@').Append(Integer.toHexString(obj.GetHashCode()).ToString()).ToString()
ovvero il full name della classe (in cui per le classi nested i "+" vengono sostituiti da "$") concatenato con "@" e con il hash code...
Questo snippet C#:
class Test{ static void Main() { System.Console.WriteLine(new a()); }}
stampa a console le mie iniziali con una chiocciola in mezzo:
a@f
Si sa che la classe a:
deriva da System.Object,
NON ha definito in modo esplicito alcun costruttore e
NON sovrascrive nel suo codice di definizione il metodo ToString.
Com'è possibile?
Le vostre idee/soluzioni fino al prossimo venerdì, nella sezione commenti.
Sotto questa riga, l'eccellente soluzione di Claudio Brotto al test "Sharp-lock Holmes". Molto bene ha condotto il ragionamento, vero? Ed eccolo inserito nel blogroll :-)
Foo.dll è un assembly .NET che definisce, almeno, i tipi A, B e C. Potrebbe essere stato generato da un qualsiasi compilatore conforme a CLS, così come da ilasm a partire da codice IL.
Essendo referenziati senza qualificatore di namespace, A, B e C devono appartenere allo stesso namespace in cui è definita D (oppure deve essere presente in precedenza una direttiva using).
A, B e C possono essere classi o interfacce. Poichè le specifiche C# impongono che, in...
Il 23 di marzo, cioè tra meno di due settimane, presenterò una sessione al workshop RONUA (ROmanian .NET User Association) a Bucarest, alla sede di Microsoft Romania (grazie a Aurelian Popa per questo invito che mi onora). L'argomento sarà sempre CLS però il contenuto e la struttura rifatti completamente rispetto alla sessione presentata a dicembre, a Milano.
RONUA, da quando ve l'ho presentato l'autunno scorso, ha fatto delle belle cose: membro INETA, 5 workshop a Bucarest (questo del 23 sarà il sesto e al quarto sono venuti Jason Zander e Brandon Bynum) e 2 a Timisoara, 122 membri e ultimamente degli...
Una specie di wrapper si potrebbe utilizzare quando si ha bisogno di un "attributo enumerato"
using System;public enum FooEnum{ Foo1, Foo2}public class FooAttribute: Attribute{ private FooEnum _foo; public FooEnum Foo { get { return _foo; } } public FooAttribute(FooEnum foo) { _foo = foo; } public static readonly FooAttribute Foo1 = new FooAttribute(FooEnum.Foo1); public static readonly FooAttribute Foo2 = new FooAttribute(FooEnum.Foo2);}
Da notare i due campi statici e in sola lettura, Foo1 e Foo2, che corrispondono ai valori del tipo enumerato. Fanno la ricerca dell'attributo, più usabile:
IList attributes = typeof(Bar).GetCustomAttributes(false);if (attributes.Contains(FooAttribute.Foo2)){ //}
dove, per esempio, abbiamo:
[Foo(FooEnum.Foo2)]class Bar{ //}
Un esempio...
Da 2 giorni sono entrato nel secondo anno di blogging, è sabato sera e quindi tempo di statistiche sceme:
Top #
Description
Web Views
1
Write a routine that counts the number of bits in a byte
313
2
Member names cannot be the same as their enclosing type
312
3
Do return an empty array instead of a null reference
282
4
Nuovo test (chi vuol essere nel mio blogroll?)
253
5
App.config e NUnit
241
6
Tutto fumo, niente fumetti
234
7
Compilazione di programmi vuoti in vari linguaggi .NET
207
8
RomanEval (i vincitori con le loro soluzioni)
204
9
Classi proxy dinamiche in .NET implementate in progetti open-source
201
10
Ma posso creare un array unidimensionale con il limite inferiore diverso da zero?
194
Top #
Description
Agg Views
1
Bug compilatore VB .NET?...
Quasi sempre, come motivo per preferire le proprietà pubbliche ai campi pubblici di istanza, si presenta quello della possibilità di validazione dei valori nella classe corrente o nelle classi derivate.
Ne ho trovato invece un altro, molto interessante, nel libro di Lowy (p. 378, sottolineatura mia):
"Neither programmatic nor declarative security can protect against untrusted code accessing public fields because no stackcalls are involved. Never provide public fields, and always use properties".
Mi sembra contraddittorio avere per una classe sealed una security action InheritanceDemand...
Succede così per la classe Executor:
namespace System.CodeDom.Compiler{ [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")] [PermissionSet(SecurityAction.InheritanceDemand, Name="FullTrust")] public sealed class Executor { // }}
La prova:
PermissionSetAttribute è uno pseudo-custom attribute, perciò troviamo InheritanceDemand come flag inheritcheck nella direttiva .permissionset.
Raf? :-)
"già vedo danzar l'altro che passerà [...]
E dirò sempre le stesse cose viste sotto mille angoli diversi"
Guccini
Il seguente snippet C#:
class D: A, B, C{ static void Main() { D d = new D(); }}
compila con:
csc /r:foo.dll test.cs
e stampa a console:
Ciao!
La dimensione dell'assembly foo.dll è molto piccola. Si chiede di ipotizzare quanto più possibile (senza reflection o tool) sul codice da cui è nata foo.dll.
Il test chiude martedì sera, le soluzioni via Contact.
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