
Brad Adams es uno de los que estuvo en el desarrollo de la plataforma .NET desde el principio, en 1998, y que también ha participado en el desarrollo de Longhorn. Me ha llamado la anteción leer en su Blog personal un post que habla del porqué de la existencia de un método DontTouchThis() en la clase Int32 y en otras similares dentro del código fuente de Rotor (la implementación de código abierto de la plataforma .NET).
Parece ser que lo hacen exclusivamente para que el compilador no les lance una advertencia por tener un miembro privado que aparentemente no se usa y que en realidad sirve para almacenar el valor asociado a la clase.
Es una tontería pero me ha parecido curioso comprobar cómo incluso en productos tan trabajados como .NET sus experimentados programadores hacen chapucillas como esta de vez en cuando. Yo os aseguro que si tengo que hacer algo similar para salir del paso acabaría pensando que seguro que hay una forma mejor (o correcta) de hacerlo y que se me está escapando ...
[Más]
Tags: Programación
7a3fddde-e7ec-4e10-9dad-9d7898ae0c03|0|.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04

Cuando restauramos una copia de seguridad de una base de datos de SQL Server desde un servidor a otro diferente es posible que los propietarios de las tablas de la base de datos recién restaurada no coincidan con el propietario que tenemos en el resto de bases de datos o con el de las tablas del sistema.
Si deseamos establecer de forma manual el propietario de una tabla (o en general de cualqueier objeto) de SQL Server podemos recurrir al procedimiento almacenado sp_changeobjectowner. Basta con abrir el analizador de consultas y escribir:
sp_changeobjectowner 'propietario.tabla', 'nuevo_propietario'
para cambiarlo. Por ejemplo:
sp_changeobjectowner 'usuario.Articulos', 'dbo'
cambiaría el propietario a 'dbo', es decir, el propietario por defecto de los objetos de una base de datos y el que normalmente se utiliza.
Tags: Programación
a25a59a6-2b25-470b-975a-8fbdd4514b7f|2|5.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04

Se trata esta de una observación que, aunque obvia, en muchos casos puede pasar inadvertida y me parece por tanto interesante destacarla aquí.
Las expresiones condicionales en C# se cortocircuitan. Esto quiere decir que se detienen las comprobaciones en cuanto no es necesario comprobar el resto de condiciones por haber hecho suficientes pruebas para determinar el resultado.
Me explico. Todo el mundo sabe que para que una condición AND proporcione un valor positivo (true) ambas condiciones que se comprueban deben ser positivas (true). Por ello, cuando C# encuentra una condición AND, y verifica que la primera de las dos condiciones que se comparan es falsa, automáticamente deja de comprobar la que falta, puesto que aunque fuese cierta el resultado será falso al serlo ya la primera y, entonces, ¿para qué seguir perdiendo el tiempo?.
Lo mismo ocurre con los otros tipos de operadores booleanos. Por ejemplo, en una expresión OR, si la primera condición es cierta ya no se sigue comproband...
[Más]
Tags: Programación
61fb20f4-6003-4974-aea2-e0b4735ee6dd|2|1.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04

Siguiendo con el post anterior de las matrices, vamos a ver ahora como emular de forma genérica la instrucción Redim Preserve de Visual Basic desde C#.
private static Array RedimPreserve(Array matriz, int nuevoTamanho) { Array m = Array.CreateInstance(matriz.GetValue(0).GetType(), nuevoTamanho); int longACopiar = nuevoTamanho; if (nuevoTamanho > matriz.Length) longACopiar = matriz.Length; Array.Copy(matriz, 0, m, 0, longACopiar); return m; }
Esta versión devuelve una matriz con el tamaño indicado y preservando los elementos contenidos en la matriz original. Se usa el método Copy de la clase Array para copiar de manera eficiente los elementos y evitar hacer un bucle.
Al igual que en el post anterior también podemos considerar la versión que transforma directamente la matriz que se le pase por referencia:
private static void RedimPreserve(ref Array matriz, int nuevoTamanho) { Array m = Array.CreateInstance(matriz.GetValue(0).GetType(), nuevoTamanho); int longACopiar = ...
[Más]
Tags: Programación
39a6df54-5ce4-44b2-8626-baadbbb9cd6b|0|.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04

En Visual Basic (clásico y .NET) hay un par de funciones para tratamiento de matrices que siempre me han parecido muy útiles. Se trata de Redim y Redim Preserve. Ambas sirven para redimensionar una matriz sin tener que volver a declararla. La diferencia entre ellas estriba en que la primera crea una amtriz nueva y se pierden los elementos que contenía, mientras que la segunda (la más interesante), permite crear una matriz nueva de diferente tamaño y que conserva los elementos que ésta contuviera previamente.
En C# la primera función tiene poco sentido ya que podemos redefinir una matriz cuando queramos, por ejemplo:
int[] matriz = new int[5];matriz = new int[8];
Ningún problema con esto. Por lo único que se me ocurre ahora mismo que podríamos necesitar la función Redim es para hacer lo anterior de forma genérica, es decir, para poder hacerlo sin importar el tipo de datos que contiene la matriz original. Esta función sería tan sencilla como la siguiente:
private Array Redim(Arr...
[Más]
Tags: Programación
53904abe-9501-4929-a563-f4fffe053e68|0|.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04

Esta cuestión es probable que a alguno le resulte trivial, si bien es cierto que a muchos programadores de C# (incluso a algunos experimentados) se les pasa por alto a veces, así que no está de más hacer un recordatorio.
La cuestión es la siguiente: ¿cómo construyo un método (función) que me permita pasarle un número cualquiera de parámetros?
Por ejemplo, imaginemos para simplificar que quiero construir una función que sume todos los enteros que se le pasen. Puedo definir varias versiones de la misma, cada una de las cuales tomando un número diferente de parámetros (un entero, dos enteros, tres, etc...). Hacerlo así, obviamente, aparte de ser una pérdida de tiempo es una cuestión bastante absurda: siempre encontraríamos un límite de parámetros, aparte de ser algo así como "matar moscas a cañonazos".
La solución en C# es muy sencilla: basta con indicarle al compilador que nuestra función necesitará un número arbitrario de parámetros, que no sabemos de antemano cuántos serán. Esto se ...
[Más]
Tags: Programación
0b1ec866-4eee-4d6a-a7e0-263a260353f8|0|.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04

Las expresiones regulares son una de las herramientas más útiles con las que contamos los programadores a la hora de analizar cadenas de texto, esto es, contenidos de archivos, expresiones y comandos, etc... Por analizar me refiero no sólo a buscar partes de textos sino a extraerlas, transformarlas, y muchas otras tareas. Se trata de un elemento que desde mi punto de vista todo programador que se precie debiera conocer.
Las expresioes regulares pueden llegar a ser muy complejas. Cuando se establece una expresión regular se genera en memoria código especializado que implementa el análisis indicado por éstas. Debido a ello cada vez que se declara una se debe generar dicho código, lo cual puede ser más o menos costoso en función de la complejidad de la expresión regular.
Para expresiones sencillas no tendremos demasiado problema. Con expresiones muy complejas que usemos mucha veces (muy a menudo) dentro de una aplicación esta compilación previa ya puede ser más significativa.
Para mejo...
[Más]
Tags: Programación
a1e968ac-28df-46ae-97a9-10961a1b4073|0|.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04

Al hilo del post de ayer me parece apropiado comentar que, para averiguar nosotros mismos qué permisos ha declarado un ensamblado (exe o dll), podemos utilizar una pequeña utilidad incluida en el SDK de la plataforma .NET llamado permview.exe.
Su sintaxis es la siguiente:
permview nombre_ensamblado.exe
o
permview nombre_ensamblado.exe /otuput: archivo.txt
para enviar los resultados a un archivo.
Lo que hace es "escupir" la información sobre los permisos declarados en formato XML, distinguiendo los permisos mínimos requeridos, los opcionales y los restringidos por la propia aplicación (tal y como vimos).
Necesitarás ejecutarlo desde la consola del SDK o de Visual Studio. Puede resultar útil como herramienta de diagnóstico.
Tags: Programación
c767b852-b2cb-4c90-9345-d14afecd23d0|0|.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04

Si desarrollamos una aplicación que deberá tener acceso a ciertos recursos del sistema restingidos normalmente por motivos de seguridad (por ejemplo acceso al sistema de archivos) es posible que en determinados casos falle por carecer de dichos permisos.
Esta carencia de permisos puede deberse a configuración del sistema (por ejemplo permisos NTFS) o bien por la cofiguración de permisos de la propia plataforma .NET (por ejemplo un ensamblado que se ejecute desde Internet o desde la Intranet).
¿No sería interesante en estos casos hacer que la aplicación, directamente, ni siquiera se ejecutase si no tiene los permisos suficientes?
Se puede conseguir este efecto declarando directamente en el ensamblado qué permisos son necesarios. Incluso más interesante aún: se pueden restringir más todavía los permisos de nuestro programa respecto a los que le otorga el propio entorno (.NET o el sistema operativo) evitando así un uso indebido de nuestras aplicaciones.
Para conseguirlo lo que se hace...
[Más]
Tags: Programación
bb00909f-7388-401c-8449-3d99ed045939|0|.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04

En mi anterior "post" comentaba la forma de conseguir que los proyectos de Visual Studio ubicados en un recurso compartido funcionasen con las mismas capacidades que los locales, lo cual pasaba por modificar la configuración de seguridad de la plataforma.
Alguna gente que ha intentado seguir el método me ha comentado que tenían un problema gordo, y es que cuando intentaban enumerar las políticas existentes en su equipo (o en cualquier otra rama), se le mostraba un error en el árbol como el que se puede observar en la siguiente figura:
(Pulsa para agrandar)
Algunas versiones no inglesas de la herramienta de configuración de .NET tienen un problema con los recursos localizados y producen este indeseable efecto. El problema se produce debido a problemas de seguridad cargando los recursos localizados y muestra en su lugar un mensaje de error en inglés.
Para solucionarlo sólo hay que resetear la cofiguración de las políticas de acceso a código y todo volverá a la normalidad. Basta con a...
[Más]
Tags: Programación
dc3a8a2a-91d3-4a5a-b871-b1aceaa27265|0|.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04

Es muy frecuente en empresas que los archivos de trabajo residan en un servidor, de forma que se mantengan centralizados (para copias de seguridad, versionamiento, etc...) y varias personas puedan trabajar al mismo tiempo sobre ellos.
En el caso de los programadores de Visual Studio esto puede suponer un problema.
Dicho problema viene dado porque, si ejecutamos Visual Studio con código que reside en un recurso compartido de la red (aunque sea una unidad "mapeada"), obtendremos advertencias a la hora de ejecutarlo e incluso errores en función del código que hayamos escrito, sobre todo en modo de depuración. Este problema se produce aunque tengamos control total para gestionar los archivos del recurso compartido.
Este comportamiento se debe a la configuración de seguridad por defecto de .NET, que trata de manera diferente al código según sea su procedencia. En el caso de código o programas ubicados en nuestra red local se usan los criterios de seguridad de "LocalIntranet", mientras qu...
[Más]
Tags: Programación
c4b546a8-1760-40a2-b335-15ab0d7ab537|0|.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04

Imaginemos que tenemos que crear un servicio Web para una tarea determinada (para simplificar, digamos, realziar una suma), y dicha tarea debe trabajar con diferentes tipos de datos.
En una clase .NET podemos crear versiones sobrecargadas de un método cada una de las cuales tomará el tipo de datos pertinente, siendo el propio compilador el que llamará a la versión sobrecargada que convenga encada caso.
En el caso de un servicio Web a priori puede parecer que no seremos capaces de obtener el mismo efecto, ya que no podemos exponer dos métodos Web con el mismo nombre. Sin embargo existe un atributo llamado MessageName que permite conseguir un efecto similar.
MessageName se utiliza para asignar alias a los métodos Web que definamos, de forma que podemos identificar de manera única a cada uno de ellos, incluso aunque el nombre asignado a la función sea el mismo. De este modo, si queremos exponer como servicio Web una clase que posee un método con varias sobrecargas sólo tenemos que emp...
[Más]
Tags: Programación
fef10c70-20f1-4cca-92f3-a41071cfbf7b|0|.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04

Cuando creamos una vesión móvil de una aplicación Web suele veir bien dar acceso a ésta desde la misma URL tanto a los clientes Web "normales" como a los usuarios que accedan desde el móvil. Hay quien directamente construye dos URLs diferentes, en plan, www.miapp.com y movil.miapp.com, pero es un poco excesivo ¿verdad?
La mejor manera de hacerlo es meter cada aplicación en su propia carpeta e incluir un código similar a esto en la página por defecto del dominio por el que se accede a ambas aplicaciones:
<script runat="server" language="c#"> public void Page_Load(Object sender, EventArgs e) { if (Request.Browser["IsMobileDevice"] == "true" ) { Response.Redirect("AppMovil/"); } else { Response.Redirect("AppWeb/"); } }</script>
Pero OJO, esto no es todo aunque pueda parecerlo.
Si lo dejamos así simplemente veremos que funcionará en muchos casos pero en muchos otros no será así. Esto se debe a que...
[Más]
Tags: Programación
7a6f185a-d50c-4996-bcec-e01df99eff47|0|.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04

A ver, cuestión peliaguda...
En progrmación COM tradicional lo que se solía utilizar a la hora de conectar con un recurso Web mediante HTTP, fuera éste una página o un servicio Web, se solía emplear la biblioteca WinHTTP o bien la clase que a tal efecto proporcionaban las bibliotecas MSXML. En ambos casos si la conectividad se obtenía a través de un Proxy era necesario configurarlo usando una utilidad externa de línea de comandos, lo cual era un verdadero problema en distribuciones grandes o que debíamos hacer manualmente. No digamos si la aplicaci´no era en un servidor Web al que sólo teníamos acceso mediante FTP.
Con .NET la vida es mucho más fácil, como ya es sabido. Así, por ejemplo, cuando vamos a consumir un servicio Web desde una aplicación .NET, al añadir una referencia Web se crea una clase que nos abstrae de la complejidad de llamar a los métodos remotos y gestionar las comunicaciones HTTP. Esta clase hereda de SoapHttpClientProtocol, que a su vez hereda de HttpWebClientPro...
[Más]
Tags: Programación
792d9c4f-9409-4b75-ace6-25165d6d2ba0|0|.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04

En algunas ocasiones puede resultar interesante averiguar desde qué otro método o métodos se ha llamado a la función actual. las utilidades pueden ser varias, por ejemplo:
Un método genérico que se use para llamar a procedimientos almacenados en una base de datos, cuyo nombre (el de los procedimientos) sea idéntico al procedimiento desde el que se llama. Puede acelerar mucho el desarrolo.
Un método que queremos que sea llamado exclusivamente desde otro procedimiento concreto.
Una función que deba ser llamada en exclusiva desde el constructor de una clase o desde Main().
Experimentar con esto, que es interesante, hombre... ;-)
En fin, el caso es que con la plataforma .NET casi cualquier cosa es posible y encima de una forma relativamente sencilla. En este caso debemos usar la clase StackTrace del espacio de nombres System.Diagnostics. Ésta nos permite navegar por la pila de llamadas de la aplicaicón obteniendo información sobre los diferentes métodos que se encuentren en ella....
[Más]
Tags: Programación
5dd99e41-6ea5-473c-a926-7aada5f07264|0|.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04

Pensemos por un momento cómo podemos construir en C# 1.0 o 1.1, una clase contenedora de datos que se pueda utilizar con la construcción foreach para iterar por los elementos que contiene...
Para empezar la clase debe implementar la interface IEnumerable. Esto tampoco supone mucho trabajo ya que, al fin y al cabo, sólo se debe implementar un método, GetEnumerator(). Ahí se empieza complicar la cosa un poco ya que este método devolverá un objeto que implementa la interfaz IEnumerator y que nosotros debemos definir también. La implementación de esta clase es algo más compleja y además debe mantener una referencia al objeto enumerable original.
Ya de por sí, como podemos comprobar, se trata de algo bastante tedioso. Pero es que además de eso en algunos casos es algo muy complicado de hacer. Por ejemplo, si queremos implementar una clase enumerable que contenga los nodos de una jerarquía (un árbol de carpetas, por ejemplo) y que, enumerándolo con foreach, nos devuelva por el orden correc...
[Más]
Tags: Programación
4c1fcfdf-af45-4f7a-89fa-e61bc1465899|0|.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04

Cuando hacemos referencia a una clase o un tipo desde nuestro código podemos emplear una ruta completa de espacios de nombres para llegar hasta él. Por ejemplo, si escribimos System.Console.ReadLine(); se busca la clase Console dentro del espacio de nombres System que está en la raíz de todos los espacios de nombres (es decir, System se encuentra en la parte más alta de la jerarquía de espacios nombres junto a otros como Cryptography, etc... y los que nosotros mismos definamos o agreguemos a un proyecto).
¿Qué pasa sin embargo si escribimos esa misma línea dentro de una clase que está contenida dentro de un espacio de nombres llamado también System?, por ejemplo:
namespace MiEmpresa.MiBiblioteca{ namespace System { class MiClase { System.Console.ReadLine(); } }}
El resultado será que la búsqueda de la clase Console comienza en el espacio de nombres actual y sólo cuando se recorra y no aparezca (porque pudiera aparecer si la hemos definido n...
[Más]
Tags: Programación
1b29ce4b-dc1e-4e8a-9c6c-4f5d1770f05d|0|.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04

Una de las grandes novedades de la versión 2.0 de la plataforma .NET son sin duda los tipos genéricos. Esta nueva característica de los lenguajes Visual Basic .NET y C# y sus correspondientes compiladores, permite escribir código genérico que, a la hora de compilarse se transforma en código específico para un tipo de datos.
Ello permite crear código de métodos, estructuras, clases e incluso interfaces sin preocuparnos por los tipos de datos que vamos a utilizar a la hora de la verdad.
Hasta la fecha cuando queríamos escribir código genérico que pudiese trabajar indistintamente con dos o más tipos de datos no nos quedaba más remedio que utilizar el tipo 'object' que es la raíz de todas las clases. Con los nuevos Generics de .NET 2.0 ya no es necesario, y nuestro código puede disfrutar de la robustez de tipos concretos sin tener que comprometerse por adelantado con ninguno.
...
[Más]
Tags: Programación
fe80aebb-fb5c-45c0-a57d-8153aca94431|0|.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04

Siguiendo la estela marcada ayer, los próximos días me dedicaré, sin prisa pero sin pausa, a comentar algunas novedades interesantes que trae la plataforma .NET 2.0, C# 2.0 y Visual Studio .NET 2005.
Hoy le toca el turno a los métodos anónimos. Éstos están pensados para simplificar la definición de manejadores de eventos cuando las tareas a realizar son simples.
Imaginemos que queremos asociar una única línea de código (o dos) como acción a realizar cuando se produzca un evento. Por ejemplo, que cuando se pulse un botón se muestre un mensaje de saludo. Lo que debíamos hacer hasta ahora era declarar una función del tipo adecuado y asociarla con un nuevo delegado al evento. Por ejemplo:
private void button1_Click(object sender, System.EventArgs e){ MessageBox.Show("Hola");}
button1.Click += new System.EventHandler(button1_Click);
Esto hace que al pulsar el botón se vea el saludo "Hola". Sin embargo es un poco engorroso para tan poca acción tener que crear una función como es...
[Más]
Tags: Programación
2589bffe-4c27-4e52-866f-0fee5a3bb377|1|4.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04

Cuando creamos una página ASP.NET con Visual Studio 1.x lo que obtenemos es un archivo '.aspx' con el HTML y etiquetas básicas de servidor para enlazar datos y para directivas de páginas, y por otro lado un archivo '.cs' o '.vb' que contiene una clase que implementa el código de la página en cuestión. A este modelo de programación se le conoce como "Code-Behind" que se podría traducir como "Código por detrás". El símil es bastante bueno ya que un usuario llama a la página ASPX pero en realidad se ejecuta por detrás y de forma transparente el código de la clase "Code-Behind". En la clase code-behind, además, se incluyen las declaraciones de los distintos controles de la página y se asignan también los manejadores de sus eventos entre otras cosas. De hecho la página final hereda de la clase code-behind, que en última instancia hereda de la clase Page.
En ASP.NET 2.0 y Visual Studio 2005 esto ha cambiado. Ahora el término nuevo a conocer es "Code-Beside" que podría traducirse como "códig...
[Más]
Tags: Programación
165d17e2-2c9b-4387-98ad-a58af5a61328|0|.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04