A grandes rasgos, esta característica nos permite especificar valores por defecto para los parámetros de nuestros métodos, ahorrándonos tiempo de codificación:
class Program
{
public static void Main(string[] args)
{
Muestra(); // Imprime 1,1
Muestra(8); // Imprime 8,1
Muestra(3,4); // Imprime 3,4
Console.ReadKey();
}
static void Muestra(int a=1, int b=1)
{
Console.WriteLine(a + "," + b);
}
}
Desde siempre, ignorante de mí, había pensado que esto no era más que una triquiñuela del compilador, un azucarillo sintáctico destinado a facilitarnos la creación de sobrecargas de forma rápida, pero, ahora que lo he estudiado algo más a fondo, resulta que no es así. De hecho, los parámetros opcionales están soportados a nivel de plataforma, y funcionan de forma algo extraña (o al menos diferente a lo que podía esperarse), por lo que es conveniente conocerlos bien para no cometer determinados errores.
En primer lugar, me ha llamado la atención que la detección de la ausencia de parámetros en la llamada y la asignación de los valores por defecto no la realiza el método en el que se han definido. Es decir, sobre el ejemplo anterior, no es el método
Muestra()
el que comprueba si se han suministrado valores para los parámetros a
y b
, ni el que le asigna los valores por defecto en caso contrario. Esta "comprobación" se realiza en tiempo de compilación (!).Esto lo demostramos muy fácilmente si descompilamos esta misma aplicación con ayuda del imprescindible Reflector, que nos mostrará el siguiente código:
class Program
{
public static void Main(string[] args)
{
Muestra(1, 1);
Muestra(8, 1);
Muestra(3, 4);
Console.ReadKey();
}
public static void Muestra([Optional, DefaultParameterValue(1)] int a,
[Optional, DefaultParameterValue(1)] int b)
{
Console.WriteLine(a + ", " + b);
}
}
Como se puede observar, se ha generado un método
Muestra()
cuyos parámetros incluyen atributos que indican su opcionalidad y el valor por defecto en cada caso.Pero lo curioso está en el método
Main()
, desde donde se hacen las llamadas, el que podemos observar que las invocaciones a Muestra()
incluyen valores para todos los parámetros, como si se tratara de constantes especificadas directamente por el desarrollador.Por tanto, no hay nada mágico en los métodos con parámetros opcionales, ni sobrecargas, ni código de comprobación o asignación insertado de forma automática. Es el propio compilador el que, en el momento de generar el código IL, extrae los valores por defecto de los parámetros no especificados en la llamada examinando los atributos presentes en la signatura y los introduce en la invocación.
Y es aquí justo donde hay que tener cuidado al utilizar los parámetros opcionales. Dado que el valor de los parámetros se determina en tiempo de compilación y se incluyen como constantes en el código IL generado, pueden producirse efectos no deseados si trabajamos con distintos ensamblados.
Veámoslo con un ejemplo, que, aunque poco real, creo que ilustrará un escenario donde los parámetros opcionales podrían jugarnos una mala pasada.
En el siguiente código, perteneciente al ensamblado
LogicaNegocio.dll
, vemos un método CalculaImporteconIva()
, que retorna un importe aplicándole el impuesto (IVA) correspondiente:public class LogicaNegocio
{
public double CalculaImporteConIva(double importe, double iva = 0.16)
{
return importe + importe*iva;
}
}
Así, podemos tener un ensamblado externo, pongamos
ERP.exe
, que haga uso de este método de la siguiente forma:public void muestraDesglose(double importe)
{
double importeTotal = logica.CalculaImporteConIVA(importe)
// Mostrarlo...
}
En el momento de compilación de
ERP.exe
, la llamada anterior quedará en el ensamblado resultante igual que si hubiéramos hecho esta llamada: double importeTotal = logica.CalculaImporteConIVA(importe, 0.16)
Si ahora se produce una subida de IVA (como lamentablemente va a ocurrir en breve), acudiríamos a modificar el valor por defecto del parámetro
iva
en el método CalculaImporteConIva()
y recompilaríamos LogicaNegocio.dll
:public class LogicaNegocio
{
public double CalculaImporteConIva(double importe, double iva = 0.18)
{
return importe + importe*iva;
}
}
Sin embargo, si no recompilamos
ERP.EXE
desde éste seguiríamos enviándole el valor anterior (0.16, recordad que este valor aparece como constante en el ensamblado), lo que podía provocar algún problema. Es decir, si queremos mantener la coherencia del sistema, nos veríamos obligados a recompilar todos los ensamblados que referencien LogicaNegocio.dll
.Conclusión: en métodos públicos, y especialmente en aquellos que serán consumidos desde ensamblados externos, es conveniente utilizar parámetros opcionales sólo cuando los valores constantes sean “verdades universales”, como las constantes matemáticas o datos que con toda seguridad no van a cambiar. No es buena idea utilizarlos para reflejar valores variables o constantes de lógica de negocio, con posibilidades de cambio aunque sean remotas.
Por último, comentar que aunque este post está centrado en C#, todas estas precauciones son igualmente válidas para Visual Basic .NET.
Publicado en: Variable not found
Publicado por José M. Aguilar a las 11:42 p. m.
Etiquetas: .net, c#, desarrollo, vb.net
En sistemas relativamente complejos como el framework MVC, puede sernos de mucha utilidad además para entender qué está pasando en determinadas circunstancias, y ayudarnos a decidir la solución óptima a un problema.
Una posibilidad es configurar Visual Studio para utilizar los servidores de símbolos de Microsoft (aquí hay un buen artículo que explica paso a paso cómo conseguirlo). Esto nos permitirá realizar el seguimiento sobre todo el framework ASP.NET, MVC incluido.
Sin embargo, dado que el código fuente de ASP.NET MVC está disponible en Codeplex, es realmente sencillo estudiar su funcionamiento de esta forma. Sólo seguir estos pasos:
- en primer lugar, descargamos el código fuente desde Codeplex y descomprimimos el archivo en cualquier carpeta,
- abrimos la solución con Visual Studio y la compilamos en modo depuración,
- abrimos (o creamos) con Visual Studio un proyecto MVC,
- eliminamos en éste las referencias que introducen las plantillas por defecto hacia el ensamblado
System.Web.Mvc
(del GAC), - añadimos la referencia hacia el ensamblado
System.Web.Mvc
que encontraremos en el directorio bin de la carpeta del código fuente del framework.
Publicado en: Variable not found
Hey, ¡estoy en twitter!
Publicado por José M. Aguilar a las 1:43 p. m.
Etiquetas: aspnetmvc, depuración, desarrollo, trucos, vs, vs2008, vs2010
TextBoxFor()
?Vamos a verlo en detalle. Partimos de una entidad del Modelo como la siguiente:
Persona
:FechaNacimiento
, podremos ver que contiene un parámetro extraño:Durante mucho tiempo no me ha llamado la atención probablemente por la costumbre de verlo en llamadas al helper
TextBox()
, donde el segundo parámetro se utilizaba para especificar el valor por defecto del <input>
. Además, dado que la edición de fechas suele realizarse de forma algo más seria (en breve hablaremos de eso por aquí) y el código generado suele eliminarse, tampoco me había fijado demasiado.Sin embargo, en cuanto observas un poco las distintas sobrecargas de TextBoxFor()
, es fácil darse cuenta de que esta llamada no es correcta. De hecho, si observamos la porción del código fuente HTML generado relativa a la edición de esta propiedad, nos encontraremos con esto:Efectivamente, el atributo extraño de la etiqueta
<input>
no es más que la propiedad Length de la cadena que estamos pasando a TextBoxFor
en su segundo parámetro, reservado en la sobrecarga de TextBoxFor que encaja con la llamada para especificar los atributos HTML personalizados:public static MvcHtmlString TextBoxFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
Object htmlAttributes
)
Curiosamente, el
TextBoxFor()
sólo es generado así en las vistas de edición (Edit), y sobre propiedades de tipo DateTime
, decimal
y double
; en las vistas de creación (Create) no ocurre este problema, ni con otros tipos de datos.Pero bueno, ya que tenemos el destornillador en la mano, cuesta muy poco trabajo dejar las cosas en su sitio ;-). Como vimos en otra ocasión, el código de las vistas que genera Visual Studio está basado en plantillas T4, y es realmente sencillo modificarlo, así que vamos a ello.
En primer lugar, acudimos a la carpeta del IDE donde se almacenan estas plantillas:
- (IDE)\Common7\IDE\ItemTemplates\CSharp\Web\MVC 2\CodeTemplates\AddView
A continuación hacemos una copia de seguridad de la plantilla llamada Edit.tt (que más vale prevenir…), la abrimos con cualquier editor de texto y buscamos en su la cadena “TextBoxFor”, que encontraremos en una porción de código como la siguiente:
<#= property.Value #>
, que es la que se encarga de emitir los atributos incorrectos. De hecho, sería simplemente dejar la línea tal y como ésta aparece en la plantilla de creación (Create.tt):Publicado en: Variable not found.
Publicado por José M. Aguilar a las 11:38 p. m.
Etiquetas: asp.net, aspnetmvc, desarrollo, error, trucos
- Hanselman explora distintas estrategias de acceso a datos en Nerdinner (EF, L2Sql, ADO, NHibernate).
Fecha: 22/05/2010 - Cómo alertar al usuario antes de que la sesión expire en asp.net Fecha: 22/05/2010
- Ejemplo de uso de formatos de fecha localizados a través de un custom ModelBinder.
One of the great things about the way in which the Microsoft ASP.NET MVC Framework is being developed is the fact that the team are publishing the source code as they go along. This makes it very simple ...
Fuente: weblogs.asp.net | Fecha: 22/05/2010 - RAMMap, una nueva herramienta de MS-SysInternals.
Have you ever wondered exactly how Windows is assigning physical memory, how much file data is cached in RAM, or how much RAM is used by the kernel and device drivers? RAMMap makes answering those questions easy. ...
Fuente: technet.microsoft.com | Fecha: 21/05/2010 - Utilización de Reflexil, paso a paso. Muy interesante.
Una de las ventajas de los compiladores que generan código intermedio es que las aplicaciones resultantes (ejecutables y librerías dinámicas) pueden desensamblarse con facilidad, reconstruyendo el código en su lenguaje original. ...
Fuente: http://www.lobosoft.es/ | Fecha: 21/05/2010 - Solución del error "'Microsoft.Jet.OLEDB.4.0' provider is not registered on the local machine" en ASP.NET corriendo en máquinas de 64 bits.
In my latest ASP.NET project, I refresh the sample data using an Excel spreadsheet from the client. After upgrading to Windows Server 2008 R2, I suddenly discovered this error:
Fuente: weblogs.asp.net | Fecha: 21/05/2010 - Utilización de MEF como mecanismo de enlace de plugins en aplicaciones ASP.NET MVC.
Scott Hanselman on Programming, User Experience, The Zen of Computers and Life in General
Fuente: http://www.hanselman.com/ | Fecha: 20/05/2010 - Ayende anuncia el lanzamiento de RavenDb
I have been talking about this for what seems like forever (over two years, if you really care to know), but it is finally out.
Fuente: ayende.com | Fecha: 20/05/2010 - Buenas prácticas para el tratamiento de excepciones en aplicaciones ASP.NET.
Helps you create functional user interfaces
Fuente: http://www.jankoatwarpspeed.com/ | Fecha: 20/05/2010 - Inicio de una serie con muy buena pinta sobre Code Contracts.
This blog post is part of a series concerning Microsoft Code Contracts. For a complete series directory, please refer to the following list. Articles without a link will be published soon. Part 01 - Introduction Part 02 - Preconditions & Postconditions
Fuente: devjourney.com | Fecha: 20/05/2010 - Los problemas con ASP.NET más frecuentemente consultados al equipo de soporte de Microsoft.
Scott Hanselman on Programming, User Experience, The Zen of Computers and Life in General.
Fuente: http://www.hanselman.com/ | Fecha: 20/05/2010 - Atributos en ASP.NET MVC 2.
Fuente: dotnetslackers.com | Fecha: 19/05/2010 - VSNewFile, un curioso plugin para VS2k8 y 2k10 para añadir rápidamente archivos a un proyecto.
Fuente: weblogs.asp.net | Fecha: 19/05/2010 - ¡Ya lo tenemos! ¡Visual Studio 2010 en castellano!
Visual Studio 2010 incorpora nuevas características mejoradas que hacen que todo el proceso de desarrollo sea más sencillo, desde el diseño a la implementación.
Fuente: http://www.microsoft.com/ | Fecha: 18/05/2010 - Lanzadas las herramientas Silverlight para VS2010.
Dan Wahlin's WebLog
Fuente: weblogs.asp.net | Fecha: 18/05/2010 - Ayende analiza el acceso a datos de MVC Music Store con EF Profiler.
I thought that it would be a good idea to take EF Prof for a spin one the sample MVC Music Store. It can illustrate some things about EF Prof and about the sample app.
Fuente: ayende.com | Fecha: 18/05/2010 - Creación de un ViewEngine personalizado con soporte para temas.
All good blogging platforms have theme support. So while working on WeBlog I initially implemented theme support by using a base controller class. The base controller class was responsible for dynamically setting the master page at runtime. ...
Fuente: http://www.codecapers.com/ | Fecha: 18/05/2010 - Cómo abrir los enlaces externos en una nueva ventana utilizando jQuery.
The site covers technical articles on Microsoft.NET, ASP.NET, MVC, C#, VB.NET, jQuery, AJAX, JavaScript, Silverlight, LINQ, VSTS, .NET Interview Questions, Windows Forms, Expression Web, Office 2007, Vista and related technologies
Fuente: http://www.dotnetcurry.com/ | Fecha: 18/05/2010 - Tres puntos de extensibilidad de ASP.NET 4 poco conocidos.
ASP.NET 4 introduces a few new extensibility APIs that live the hermit lifestyle away from the public eye. They’re not exactly hidden - they are well documented on MSDN - but they aren’t well publicized. It’s about time we shine a spotlight on them.
Fuente: haacked.com | Fecha: 17/05/2010 - Método extensor para conocer el área, controlador y acción actual, por ejemplo, para maquetar menús sensibles a la ubicación actual del usuario.
Have you ever needed to detect what part of the application is currently being viewed? This might be a bigger issue if you write a lot of shared/partial views or custom display or editor templates. Another ...
Fuente: geekswithblogs.net | Fecha: 15/05/2010 - Music Store: Tutorial y aplicación de ejemplo de ASP.NET MVC 2
All posted code is published under Public Domain license unless otherwise stated. All content is published under a Creative Commons Attribution License
Fuente: weblogs.asp.net | Fecha: 14/05/2010 - Estensión a T4MVC para renderizar vistas parciales.
T4MVC is a helpful template for your MVC projects. You can follow the directions on David’s blog to get started; that should give you a quick understanding of what T4MVC is capable of. If you’ve yet to ...
Fuente: http://www.weirdlover.com/ | Fecha: 13/05/2010 - Utilización de FCKEditor con ASP.NET MVC.
Stefan Kamphuis of Giraffe IT on DotNetNuke, asp.net, Microsoft, C#, VB.Net, and more...
Fuente: msmvps.com | Fecha: 13/05/2010 - ASP.NET MVC y Webforms en el mismo proyecto, o cómo mezclar churras con merinas.
One of the nice things about ASP.NET MVC and its older brother ASP.NET WebForms is that they are both built on top of the ASP.NET runtime environment. The advantage of this is that, you can still run them side by side even though MVC and WebForms are different frameworks.
Fuente: weblogs.asp.net | Fecha: 11/05/2010 - Interesante serie de posts sobre ASP.NET MVC y jQuery.
This is me blogging the development of a project, codenamed 'Raven' for the company which gainfully employs me. I program on the .NET stack, am lovin' Windows 7 and Visual Studio 2010. Truth be told, the only ones that call me 'Mister James' are the three- and four-year-olds at Sunday school. ...
Fuente: theycallmemrjames.blogspot.com | Fecha: 11/05/2010 - Fijación de proyectos y soluciones a la lista de elementos abiertos recientemente en Visual Studio 2010..
ASP.NET, Visual Studio, ASP.NET 2.0, .NET
Fuente: weblogs.asp.net | Fecha: 11/05/2010 - Grid con paginación, ordenación y filtro utilizando componentes de MVC Contrib.
This post walks you through creating a UI for paging, sorting and filtering a list of data items. It makes use of the excellent MVCContrib Grid and Pager Html UI helpers. A sample project is attached at the bottom.
Fuente: weblogs.asp.net | Fecha: 10/05/2010
Publicado en: Variable not found
Debe ser por eso que me divierten y me identifico tanto con los posts que enumeran estos hábitos tan comunes, como el clásico las “20 respuestas más utilizadas por los desarrolladores cuando sus programas no funcionan”, que pulula por la red desde hace muchos años y del que he encontrado versiones en todos los idiomas, por lo que soy absolutamente incapaz de citar la fuente exacta.
El hecho es que justo en el momento en que se nos informa de que algo ha fallado en una de nuestras aplicaciones, el cerebro comienza a trabajar aceleradamente en busca de una
Y es que, al final, seguro que todos acabamos diciendo aproximadamente lo mismo…
20. “¡Qué raro!”. Primera regla del desarrollador experimentado: mostrar asombro cuando algo falla. Alguien que no se extrañe de la aparición de un error puede aparentar ser bastante mediocre. Hay quien incluso, para acentuar más aún su profesionalidad, añade “¡Imposible!”.
19. “Nunca había pasado antes”. Por si no queda claro con el conjunto de exclamaciones anteriores, apostillar con esta declaración deja claro que os encontráis ante algo insólito. Esto, además, puede ser útil para despertar el espíritu aventurero en tu interlocutor, y hacerlo partícipe en el enfrentamiento a lo desconocido que estáis a punto de comenzar.
18. “Ayer funcionaba”. Busca un soporte sólido para aferrarte, una referencia fiable como esa. Decir que ayer funcionaba es una afirmación ideal: difícil de probar, y si estás ante alguien cándido e inocente, será suficiente para convencerlo de que el error se ha generado hoy mismo, como por arte de magia.
17. “¿Cómo es posible?”. Otra oportunidad para demostrar tu asombro, que además surte mayor efecto si lo sigues con una explicación que tu interlocutor no sea capaz de entender: “cuando I,J,K y no M,N,L es imposible que X,Y,Z”.
16. “Debe ser un problema hardware”. Segunda regla del desarrollador experimentado: si la cosa se complica, puedes ir abriendo el camino a nuevas posibilidades, alejadas de nuestra responsabilidad. Nada podemos hacer contra fallos en la máquina, nosotros sólo entendemos de software. De hecho, si somos incapaces de dar con el problema (y por tanto incapaces de solucionarlo), echar las culpas al metal es una vía de salida de lo más airosa.
15. “¿Qué hiciste mal para que fallara?”. Duda siempre de la lucidez del usuario. Si lo acusas de ser un zoquete tendrá que dedicar su tiempo de proceso a defender su postura, y no a vapulearte como te mereces.
14. “Hay algo raro en tus datos”. Es una variación más ligera del caso anterior; estás descargando responsabilidad sobre el usuario, aunque de forma menos agresiva, pues no es un ataque directo a su persona, sino a los datos que utiliza. Esta fórmula puede ser útil y prudente si, por ejemplo, el usuario del sistema es tu jefe.
13. “¡No he tocado ese módulo en semanas!”. Eso es, deja claro que tú no has tocado nada, y que por tanto la responsabilidad no es tuya. Si el módulo funcionaba hace un mes y no has tocado nada, está claro que la culpa el del usuario, del entorno, o del propio desgaste, como las ruedas de un coche.
12. “Debes estar utilizando una versión incorrecta”. Esta es una técnica avanzada para aplicar una vez te has percatado, en silencio claro está, de que había un error tuyo en tu aplicación. Acusa al usuario de utilizar una versión antigua del software, y suminístrale la versión correcta, en la que obviamente ya has parcheado el error.
11. “Se trata sólo de una casualidad”. Utiliza el azar como causa de los problemas; es impredecible, incontrolable y misterioso, una cortina de humo ideal para esconder nuestras meteduras de pata.
10. “Uno no puede probarlo todo”. No somos Dioses… quizás estemos muy cerca, pero no lo somos. Esta frase, a utilizar sólo en casos señalados, puede mostrar humildad y apelar a la bondad del interlocutor para disminuir la tensión. O también, puede servir para arremeter contra tu organización, la falta de recursos, de tiempo, etc., que el usuario empatizará y lamentará contigo.
9. “Eso no puede ser la causa del problema”. Sé tajante; aunque tenga razón, no permitas que un usuario listillo te revele el motivo exacto por el que ha fallado tu aplicación, pues nadie la conoce mejor que tú. Si después de usar esta frase confirmas que la causa era la apuntada por este individuo, no lo reconozcas, y utiliza verborrea técnica para desviar la atención a otras causas.
8. “Eso funciona, aunque no lo he probado”. Un desarrollador profesional no necesita probar las cosas para saber que funcionan, eso es cosa de débiles e inseguros. Una afirmación tan rotunda desequilibrará al interlocutor y lo hará dudar de su criterio a la hora de detectar el error, momento que puedes aprovechar para rematar con cualquier otra frase.
7. “Alguien debe haber cambiado mi código”. Otra regla de oro del desarrollador, aunque compartida con otras profesiones: échale las culpas a otro. Una vez demostrado que hay un fallo y que no puedes hacer responsable al usuario, no hay nada mejor que echar la culpa a los compañeros. Y si crees que no es ético, recuerda: ellos también lo harían.
6. “¿Has comprobado si tienes un virus?”. Los virus, esos seres misteriosos que sólo podemos comprender los iniciados y de los que todo el mundo ha oído historias terribles, son también firmes candidatos a salvarnos el trasero cuando la cosa se está poniendo peligrosa. Dado que la respuesta a esta pregunta
5. “Bueno, no funciona, pero mola, ¿eh?”. Ante una encerrona, apela al sentido del humor de tu interlocutor. Intenta detectar algún aspecto positivo del desastre, y preséntalo de forma atractiva para el usuario. ¿Un proceso tarda demasiado? Así tienes más tiempo para estirar los músculos; ¿La aplicación se cierra violentamente? Así puedes apagar antes el equipo e irte a casa; ¿Una BSOD? Fíjate qué fondo de pantalla azul eléctrico tan espectacular te pone el programa cuando falla.
4. “No puedes usar esa versión en tu sistema” Cuando el número de errores sea tan alto que pueda poner en peligro tu credibilidad como profesional, no reconozcas haberlos cometido; utiliza motivos estructurales como el hardware, los virus, o el versionado de sistemas para hacerles ver que eres totalmente inocente.
3. “¿Por qué quieres hacerlo así?” Una posibilidad muy socorrida es a veces instruir al usuario para que realice las tareas justo de la forma en que la aplicación funciona correctamente, censurándole rápida y tajantemente los intentos de salirse del camino marcado. A veces es más fácil adaptar el usuario a la aplicación que viceversa.
2. “¿Dónde estabas cuando el programa falló?” Ideal para aplicaciones que funcionan como procesos por lotes, o para intentar culpar al usuario de su ausencia en un momento vital como en el que se produjo el problema. Sobre todo si sabemos que el usuario es tendente a despistarse, esta puede ser un arma realmente interesante.
1. “No es un error, es que el programa funciona así”. Aprovecha la delgada línea que separa un bug de una feature. Esta técnica avanzada te permitirá desviar la atención hacia las personas que decidieron las funcionalidades, recogieron los requisitos, o validaron el software, pero nunca hacia el desarrollador que simplemente siguió las instrucciones.
Y por último, la frase más utilizada sin duda por los desarrolladores:
0. “¡En mi máquina funciona!” Desconcierta al interlocutor, y queda como debes, por encima de todos. El software funciona en entornos controlados como el tuyo, propios de un experto, donde todo está perfectamente en orden y lejos del alcance de las manazas del usuario final.
Eso sí, hay que estar preparados para una respuesta como la siguiente:
Publicado en: Variable not found