Una dudilla sobre C#

Hola… a punto todos para comernos las uvas????

Antes de que lo hagáis y os lanceis luego a brindar con cava por el nuevo año, y una cosa lleve a la otra y no esteis en condiciones, digamos de… pensar mucho, a ver si alguien me sabe responder una dudilla que me ha surgido hoy.

¿Porque este código no compila?

public class Foo
{
    public string Name { get { return string.Empty; } }
    public string Name() { return string.Empty ; }
}

Por si alguien (como yo) se pensaba que eso compilaba, pues no. Visual Studio se queja con un claro y explícito error CS0102: The type ‘ConsoleApplication232.Foo’ already contains a definition for ‘Name’.

Alguien sabe el porque de esta limitación? Es decir, porque han evitado que podamos hacer esto? Alguien tiene alguna idea?

Epa!!! Buen año a tod@s y que el 2009 os sea lo más propicio posible!!!! Y no os comáis las uvas antes de tiempo! Recordad que el último minuto de este 2008 tiene un segundillo de más!!! xD

Mi carta a los reyes…

Aunque sería para unos reyes que pasaran más allá del 2010, pero bueno… por pedir que no quede 😛

Estas son las cosas que me gustaría que algun dia se incorporasen a C#. Como son fiestas mágicas, pues aquí van para ver si los chicos de Redmond se animan y para algún milenio las tenemos…

Pongo ideas al margen de si son posibles/factibles con el CLR actual… simplemente son cosas que me gustarían que estuviesen en el lenguaje. Solo pongo las ideas y un ejemplo de lo que me gustaría, sin desarrollarlas a fondo… 🙂

1. Conceptos en genéricos

La idea es poder representar como restricción de un tipo genérico algo más allá que una interfaz. Por ejemplo:

concept HasHandle
{
    IntPtr Handle{ get; }        
}

class Foo
{
    public static void Main(string[] args)
    {
        new Foo().Bar(new Form());
    }

    public void Bar<T> (T t)
        where T : HasHandle
        {
            DoWork(t.Handle);
        }
}

Este código deberia compilar porque el concepto HasHandle define una propiedad llamada Handle de tipo IntPtr. El mètode genérico Bar<T> utiliza esta propiedad. Y la llamada a Bar con un paramétro Form satisface el concepto, puesto que la clase Form tiene una propiedad IntPtr llamada Handle.

Los conceptos deberían poder ser genéricos a su vez:

concept HasXXX<T>
{
    T XXX{ get; set;}        
}

class Foo
{
    public void Bar<T,U> (T t)
        where T : HasXXX<U>
        {
            U u = t.XXX;
        }
}

El método Bar<T,U> debería poder llamarse con cualquier tipo T que tuviese una propiedad U XXX {get; set;}

Los conceptos deberían poder hacer referencia a la existencia de métodos estáticos:

concept Comparable<T>
{
    bool operator > (T t1, T t2);
}

class Foo
{
    void Bar<T> (IEnumerable<T> items)
        where T : Comparable<T>
    {
    }
}

El método Bar<T> debería poder llamarse con cualquier tipo T que tuviese definido el operador ‘>’ (aunque este esté definido de forma estática).

2. Constantes binarias

Pues eso mismo…

int i = 0b00001100;

Fácil, no??

3. Tipos anónimos que puedan implementar una interfaz

Los tipos anónimos tal y como estan ahora sirven para poco más que para LINQ. Sería interesante que pudiesen implementar una interfaz y que pudiesen ser devueltos a través de referencias a dicha interfaz:

interface ISomeInterface
{
    int Foo(int);
}

class Bar
{
    ISomeInterface Baz()
    {
        return new ISomeInterface  { void Foo(int i) { return i+1;} };
    }
}

El tipo anónimo creado en el método Baz, implementa la interfaz ISomeInterface y es devuelto a través de una referencia a dicha interfaz.

4. Referencias const

Al estilo de C++. Mira que esto es simple y útil y no se porque no lo han metido… Para más info: http://www.cprogramming.com/tutorial/const_correctness.html.

5. Enumeraciones con cualquier tipo

Estaría bien que los enums pudieran tener cualquier tipo base:

class Planeta
{
    long Diametro { get; set; }
    long DistanciaSol { get; set; }
}
enum SistemaSolar<Planeta>
{
    Mercurio = new Planeta() { Diametro=4879, DistanciaSol=46000000},
    Tierra = new Planeta() { Diametro=12742, DistanciaSol=150000000}
}
class Foo()
{
    Bar () { this.Baz(SistemaSolar.Mercurio);}
    Baz(SistemaSolar p)
    {
        if (p.Diametro > 10000) { ... }
    }
}

El enum SistemaSolar se define como una enumeración de objetos de la clase Planeta.

El método Foo.Baz acepta como parámetro sólo SistemaSolar.Mercurio o SistemaSolar.Tierra. Pasarle cualquier otro objeto Planeta no debería compilar.

Felices fiestaaaaaaaaaaaaaaaaaaaaaaas!

Bueno… paro ya de pedir cosas, jejeeee… 🙂

Solo desearos a todos los geeks unas felices fiestas, llenas de alegría, familia, ceros y unos…

… y que el tió os cague muchos regaloooooooooooooooooooooooooooooooos!!!!

Duda metafísica sobre “contravarianza” en delegates

Hola… hoy voy a poner un post sobre una dudilla metafísica que me ha surgido, concretamente relativa a los delegates. Y he pensado… que mejor sitio que ponerla que aquí??? 😉

Los delegates en C# 2.0 son contravariantes, es decir un delegate a un método que espera un parámetro tipo X aceptará cualquier método que espere un parámetro de cualquier tipo base de X.

Es decir, el siguiente código funciona bien:

delegate void Foo(Derived d);
public class Base { }
public class Derived : Base { }
public class SomeCode
{
    SomeCode()
    {
        Foo foo = new Foo(this.SomeMethod);
    }
    private void SomeMethod(Base b) { }
}

Todos entendemos la lógica que hay tras ello: al ser todos los objetos Derived, objetos Base, es evidente que cualquier método que trate con objetos Base, lo podrá hacer con objetos Derived, y por ello el método SomeMethod es un destino bueno para el delegate Foo.

Ahora bien, imaginemos que tenemos el siguiente código:

delegate void Foo(Derived d);
public class Base { }
public class Derived 
{
    public static implicit operator Base(Derived d) { return new Base(); }
}
public class SomeCode
{
    SomeCode()
    {
        Foo foo = new Foo(this.SomeMethod);
    }
    private void SomeMethod(Base b) { }
}

En este caso el código no compila, el compilador se queja con un No overload for ‘SomeCode.SomeMethod(Base)’ matches delegate ‘Foo’.

La duda metafísica es… creeis que debería compilar? En cierto (lo pongo en cursiva) todos los objetos Derived tambien son objetos Base, puesto que hay definida una conversión implícita de Derived a Base… con lo que podríamos entender que hay una cierta contravarianza.

O creeis que no? Que ya está bien que no compile puesto que el operador de conversión no puede representar nunca una relación is-a y por lo tanto la contravarianza no tiene sentido…

MMmmm… yo reconozco que no estoy 100% posicionado a favor de ninguna opción…

Saludos!

El valor de una certificación.

Bueno, aviso: estoy cabreado… y este post será polémico. Quien avisa no es traidor.

Estas últimas semanas me he sacado dos MCPs, en concreto el 70-529 y el 70-549, es decir el MCTS y el MCPD de aplicaciones distribuídas. No voy a hablar sobre si son fáciles o difíciles o si se ajustan a lo que realmente uno se encuentra en el mundo real, no… quiero exponer algo que ya hace tiempo me preocupa y me mosquea a partes iguales. Antes de nada he de decir que no tenía muy claro si escribir este post. Por hastío básicamente… lo digo porque lo que escribiré ahora es, lamentablemente, muy parecido a lo que escribí en mi antiguo blog en la casi-extinta clearscreen (un tick de silencio). Aquí dejo el enlace al post que escribí hará casi tres años, por si a alguien le apetece leerlo.

Antes de hacer ambos exámenes, eché una ojeada a esos pdfs que tienen preguntas parecidas a las del exámen, junto con sus respuestas (¿no hace falta poner nombres, verdad?). Lo que vi fue descorazonador… bueno, lo hubiese sido si no supiera de que va el tema, vamos… ahora ya empieza a resbalarme todo…

El caso del 70-529 es flagrante: todas (y todas significa todas) las preguntas exámen estaban en el pdf. Además éste estaba bastante bien (había algunas preguntas que creo que estaban mal y algunas otras que estaban mal seguro) o sea que alguien simplemente empollándose el pdf se sacaba perfectamente el exámen.

El caso del 70-549 no fue tan brutal. De las 60 preguntas que tenia el exámen había unas 45 que estaban en el pdf (ya veis, aunque no tan brutal sigue siendo lamentable). Eso sí, al menos el pdf del 70-549 estaba un poco peor (tenia más respuestas incorrectas)… aun así, empollándoselo uno aprueba el exámen.

No quiero ni voy a criticar a quien se empolla estos pdfs para sacarse MCPs… quiero criticar a quien permite explícitamente que esto siga así. A quien en mi opinión es el máximo culpable (aunque sea por inacción). Es decir, a Microsoft. Creía que la certificación servía para acreditar unos determinados conocimientos, pero veo que simplemente es otra patética herramienta para hacer dinero. Da igual que la certificación esté tan prostituída que los exámenes se encuentren en internet, mientras la gente siga pagando para hacerlos (donde digo gente también se puede leer empresas que quieran ser pon-aquí-tu-material-preferido certified partner). Anda que no sería fácil evitar estos pdfs teniendo un pool de centenares de preguntas por exámen en lugar de menos de 80 (el pdf del 70-529 tenia menos de 80 preguntas y repito: todas me salieron en el exámen). Y también ir cambiando las preguntas cada cierto tiempo ayudaría. ¿Cuanto le costaría hacer todo esto a Microsoft? ¿Por que no lo hace? Y más preguntas… ¿cómo es posible que determinadas academias ofrezcan un cursillo de pongamos 50 horas tras el cual garanticen tener MCPD? ¿No se suponía que estas certificaciones eran para gente con determinada experiencia? ¿50 horas en un cursillo es esta experiencia?

De ahí el título del post: ¿cuál es el valor de una certificación cuyos exámenes se encuentran (con respuestas incluídas) en internet? ¿Porque debo dedicar esfuerzo y dinero (esos exámenes no son gratis) en sacarme estas certificaciones? ¿Debo seguir jugando a este juego? ¿Hará algo al respecto Microsoft? (esta última pregunta es retórica, lo aclaro por si acaso).

¿Alguna respuesta convincente?