martes 25 de noviembre de 2008
PDC 2008: The Future of C# 4.0 (2/3)
Seguimos comentando la presentación de Anders Hejlsberg sobre el futuro de C# y las novedades que nos aguardan para la próxima versión.
Ahora le toca el turno a una característica que los usuarios de VB.NET disfrutan también desde siempre y que personalmente no entiendo cómo ha tardado tanto en aparecer en C#: Llamadas a métodos con valores por defecto para los parámetros.
Si has tocado C++ seguramente has echado de menos escribir algo como:
void SomeMethod(string connectionString, int timeout = 1000) {...};
...
SomeMethod("myConnectionString"); //1000ms timeout
SomeMethod("otherConnectionString", 3000);
Esta limitación se puede solventar fácilmente, simplemente escribiendo varias sobrecargas para el método:
void SomeMethod(string connectionString , int timeout = 1000) {...};
void SomeMethod(string connectionString):this (connectionString, 1000) {...}
SomeMethod("myConnectionString"); //1000ms timeout
SomeMethod("otherConnectionString", 3000);Pero escribir más sobrecargas implica... escribir más código. Eso es algo que el propio compilador podría hacer y que de hecho ya hacía en otros lenguajes, por lo que realmente era una carencia ... curiosa.
Quizá para implorar el perdón de las hordas, además de prometer que a partir de ahora se intentaría que ambos lenguajes (VB.NET y C#) evolucionen de forma paralela para mantener en ambos funcionalidad similar, se añadirá la posibilidad de utilizar parámetros con nombre dentro de métodos con parámetros por defecto. Eso implica que ahora podremos elegir qué parametros por defecto utilizar, y no estaremos limitados a utilizarlos en el orden declarado. Por ejemploFusilando de nuevo, si tenemos
public StreamReader OpenTextFile(Podríamos llamarlo así:
string path,
Encoding encoding = null,
bool detectEncoding = true,
int bufferSize = 1024);
OpenTextFile("C:\mypath");
OpenTextFile("C:\mypath",Encoding.ASCII);
OpenTextFile("C:\mypath",Encoding.ASCII, false);
OpenTextFile("C:\mypath",Encoding.ASCII, false, 2048);Pero no podríamos llamar a dicho método así: OpenTextFile(2048);
Es decir, el orden de uso de los parámetros depende de su declaración. De hecho todos los parámetros por defecto deben ser los últimos que se declaren (los que estén "más a la derecha" en la firma del método)
Sin embargo con parámetros por nombre podremos definir el nombre del parámetro que queremos establecer y el compilador utilizará los valores por defecto para el resto si procede. Así, ahora podríamos hacer:
OpenTextFile(bufferSize : 2048, path :"C:\MyPath");Siendo esta llamada equivalente a
OpenTextFile("C:\MyPath", null, true, 2048);Por supuesto los parámetros que no tienen un valor por defecto DEBEN aparecer en la llamada. Además los parámetros con nombre se evaluarán en el orden en que aparezcan en la llamada, y no en el orden en el que estén definidos.
Para la próxima entrada comentaremos la última novedad, algo por lo que también hubiera matado pagado: covarianza y contra-varianza con generics.





2 Comentarios:
Yo tengo mi teoría de por qué no añadieron esa característica hasta ahora.
Los parámetros por defecto facilitan la llamada a los métodos, pero impiden la sobrecarga en algunos casos.
public void miMetodoDeLaLeche(int a, int b = 5) {
// Código que hace una cosa
}
public void miMetodoDeLaLeche(int a) {
// Código que hace otra cosa diferente
}
¿Cómo se diferencian estos dos casos si se invoca al primer método haciendo uso del parámetro por defecto? Habría que renombrar alguno de ellos. Ante la duda sobre cómo diseñar esa característica en las versiones de C# actuales, supongo que tiraron por lo más fácil (no incluir parámetros por defecto), o simplemente copiaron Java XD.
Hombre, es que en ese caso IMHO sería un fallo en el diseño, porque tener dos métodos sobrecargados que hagan cosas distintas no creo que sea muy apropiado.
Además en ese caso lo que se podría hacer es simplemente no usar parámetros por defecto.
De hecho si usas número variable de parámetros, que si han incluido (que yo sepa desde siempre pero al menos desde la v2.0) tienes un problema similar:
public void miMetodoDeLaLeche(int a, params int[] b) {
// Código que hace una cosa
}
public void miMetodoDeLaLeche(int a) {
// Código que hace otra cosa diferente
}
Como los parámetros son opcionales, si haces
miMetodoDeLaLeche(5);
el compilador no sabe cual resolver.
Supongo que copiaron a Java :P
Publicar un comentario en la entrada