Delegate

Un delegate es un objeto que hace referencia a uno o más métodos, previamente declarados en nuestra aplicación. Todos aquellos métodos que sean incluidos en él, tienen la particularidad de ser idénticos en cuanto al retorno y los parámetros que recibe. ¿Con todo esto qué quiero decir? ¿Cuál es el objetivo? La magia está en que, si nosotros creamos un delegate con una serie de métodos asociados, al llamar al mismo lanzará un método detrás de otro pasándole a cada uno de ellos el valor(es) con el que invocamos al delegate. Veamos un ejemplo:

delegate void Delegado(string cadena);

Si mi delegado es como el anterior, todos los métodos que contenga no deberán de retornar nada y necesitan como parámetro un string.
Esa sería la forma de declarar un delegado. Para continuar con el ejemplo, voy a crear dos métodos que cumplan las características del delegado (Esto es muy importante porque, de no ser así, lanzará una excepción).

public void Saludo(string cadena)
{
    lblResult.Text += "Hola " + cadena;
}

public void Despedida(string cadena)
{
   lblResult.Text += " Adios " + cadena;
}

La forma de asignar un método sería la siguiente:

protected void btnDelegado_Click(object sender, EventArgs e)
{
    Delegado delegando = Saludo;
    delegando += Despedida;
    delegando(txtCadena.Text);
}

Para asignar el método Saludo, simplemente utilizo el símbolo = y, para añadir el método Despedida +=
Si quisiéramos eliminar en algún momento del delegado uno de los métodos, únicamente tendríamos que utilizar -= nombre_del_Metodo

¡Saludos!

Cliente JSON para WCF

En un post anterior, mostré como crear un servicio web con Windows Communication Foundation. Para consumir el mismo, vamos a implementar un pequeño cliente JSON con JQuery.
Creamos un proyecto ASP.NET Web Application:

Antes de comenzar con nuestro código, necesitamos la librería de JQuery, la cual podemos descargar en este enlace para posteriormente añadirla a nuestra solución.
Por otro lado, vamos a crear un nuevo archivo JScript, llamado JSON.js, donde implementaremos la funcionalidad que llamará a nuestro servicio y recogerá el resultado. Nuestro proyecto quedaría de la siguiente manera:

He utilizado la página Default.aspx para mostrar dos textbox y poder solicitar los valores al usuario, además de dos botones con los que llamaremos al servicio.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="ClienteJSON._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "<a href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd</a>">
<html xmlns="<a href="http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</a>">
<head runat="server">
    <title>Cliente JSON</title>
</head>
<body>
    <div id="Calculos">
        <div>
            <div>
                <label id="lblNumeroUno">
                    Introduce número:</label>
                <input type="text" id="txtNumUno" />
            </div>
            <div>
                <label id="lblNumeroDos">
                    Introduce otro número:</label>
                <input type="text" id="txtNumDos" />
            </div>
            <div>
                <input type="button" id="btnSumar" value="Sumar" />
                <input type="button" id="btnRestar" value="Restar" />
            </div>
        </div>
    </div>

    <script type="text/javascript" src="jquery-1.3.2.js"></script>

    <script type="text/javascript" src="JSON.js"></script>

</body>
</html>

Por último, sólo nos quedaría invocar al servicio web y mostrar el resultado que nos aporta, en función de si queremos Sumar o Restar los número que introducimos a través de la interfaz. Abrimos el archivo JSON.js e introducimos lo siguiente:

$("#btnSumar").bind("click", function(e) {
    var params = { "a": $('#txtNumUno').val(), "b": $('#txtNumDos').val() };
    $.ajax({
        type: "GET",
        url: "http://localhost/WCF/Service.svc/json/Suma",
        data: params,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(msg) {
            alert("Resultado Suma: " + msg.d.Result);
        }
    });
});
$("#btnRestar").bind("click", function(e) {
    var params = { "a": $('#txtNumUno').val(), "b": $('#txtNumDos').val() };
    $.ajax({
        type: "GET",
        url: "http://localhost/WCF/Service.svc/json/Resta",
        data: params,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(msg) {
            alert("Resultado Resta: " + msg.d.Result);
        }
    });
});

La verdad es que, teniendo JQuery, es bastante simple realizar este tipo de funcionalidad. He utilizado el método Bind, para asignarles el evento a cada uno de nuestros botones. De esta manera, no tenemos que introducir ningún código de javascript en nuestro aspx. Más adelante me gustaría enfocarme en la manera de funcionar de esta librería.

En el mismo sitio donde bindeamos el evento click a nuestro botón, creamos la función que se va a ejecutar.
Utilizamos la variable params para montar nuestra cadena de parámetros. Hay que tener en cuenta que el nombre de cada parámetro se debe corresponder con el que tienen en el servicio web (en este caso a y b).
Creamos un objeto ajax con los atributos type (el tipo de HTTP Verb que vamos a utilizar), la url donde se aloja nuestro servicio, seguido del método que vamos a invocar, en data le pasamos los parámetros necesarios para el cálculo solicitado, contentType indica cómo va a evaluar JQuery la respuesta y cómo nos la va a devolver (En el caso de JSON evalúa la respuesta como tal y nos retorna un objeto javascript), dataType es el formato en el que estamos pasando nuestro parámetros y en la parte success se adjunta la función que se lanzará cuando haya terminado el proceso en caso de éxito. En un principio, esto es lo mínimo que debemos usar.

Si arrancamos la aplicación, ya tenemos nuestra Suma y nuestra Resta funcionando con un servicio web en WCF y su cliente en JSON.

Descargar ejemplo ClienteJSON.zip

¡Saludos!

Soporte Intellisense para JQuery en Visual Studio 2008

Por el momento, hasta que no podamos disfrutar del todo de Visual Studio 2010, la versión 2008 no tiene por defecto el soporte para el intellisense de JQuery. ¡Pero todo tiene solución! Ya que entiendo que es una gran comodidad para el programador visualizar las posibilidades que nos ofrece una librería como esta.

En primer lugar debemos tener instalado el SP1 para Visual Studio 2008 (o también, desde ese mismo link, podemos conseguir el Visual Studio 2008 Express Editions con el SP1 integrado)  y un hotfix que podéis descargar de esta dirección.

Una vez que tenemos listo nuestro Visual Studio, ya podemos descargar los vsdoc.js que nos ofrece JQuery. Si accedemos al listado de descargas, podemos visualizar los vsdocs disponibles desde la versión 1.2.6 en adelante. Los archivos necesarios son aquellos que en la descripción aparece lo siguiente: Visual Studio Autocomplete Documentation.

Descargamos el vsdoc para la versión que estamos utilizando de JQuery y lo agregamos en nuestro proyecto. Al comienzo de los archivos js, indicamos como referencia el vsdoc que hemos añadido de la siguiente forma:

/// <reference path="~/jquery-1.3.2-vsdoc2.js"/>

Por último, podemos comprobar como efectivamente nos muestra el listado de posibilidades y una pequeña descripción de el uso de las mismas.

¡Saludos!

System.InvalidOperationException IIS 7

En el post anterior, comentaba algunos comandos para poder solucionar los problemas que pudiéramos tener con nuestras aplicaciones con WCF  y nuestro IIS. Con esos dos pasos, conseguí que funcionara perfectamente en Windows XP (IIS 5.1)… pero al llegar a casa y volver a ejecutar la aplicación en IIS 7 con Windows 7… Llega de nuevo la desilusión. El caso es que lo conseguí arreglar cuando tenía la versión de 32bits, pero me bajé la de 64bits y claro, para que voy a apuntarme este tipo de cosas ;)
El error que me mostraba era el siguiente:

Después de dar muchísimas vueltas, leer blogs, preguntar a Google de cuatrocientas formas distintas, etc. nada me sirvió y la verdad es que sigo sin entender bien por qué. El caso es que se me ocurre la genial idea de montarlo como Sitio web en vez de Directorio Virtual y ahora le parece estupendo.

La verdad es que no entiendo bien por qué no acepta el servicio como un directorio virtual, pero es la única forma en la que he conseguido que me funcionara con WCF en Windows 7 y la verdad no recuerdo si llegué a la misma conclusión cuando tenía instalada la versión de 32bits.
¿Alguien sabe otra solución o conoce la causa de esto? En cualquier caso, si a alguien le sucede lo mismo que a mí y no encuentra otra solución alternativa a esta, siempre nos quedarán los sitios web :)

¡Saludos!

Failed to access IIS metabase

Y si es que no… ¡A sufrir se ha dicho! Cada vez que formateo y tengo que organizar las extensiones del IIS me vuelvo loca para volver a lo que tenía configurado y pensé que nunca más volvería a sufrir. Este error pasa justamente por esto y, antes de volvemos locos de remate, abrimos una línea de comandos y ejecutamos lo siguiente: 

%system root%Microsoft.NETFrameworkversionNumberaspnet_regiis.exe -i

Por ejemplo:

C:WINDOWSMicrosoft.NETFrameworkv2.0.50727>aspnet_regiis.exe -i

Sin irnos muy lejos, es posible que si justamente hemos instalado IIS después del Visual Studio, tampoco tengamos las extensiones svc  y nuestras aplicaciones WCF no funcionen. Os dejo también este otro comando para matar dos pájaros de un tiro:

C:WINDOWSMicrosoft.NETFrameworkv3.0Windows Communication Foundation>ServiceModelReg.exe -i

Espero que haya sido de utilidad :)

¡Saludos!

Creando un Web Service con WCF

Windows Communication Foundation fue una de las novedades de .NET Framework 3.0, la cual permite la creación de sistemas distribuidos orientados a servicios.
Con Visual Studio 2008, disponemos de una plantilla que nos genera todo lo necesario para empezar a trabajar con ello. No obstante, en esta ocasión, dejaremos de lado la misma para poder visualizar claramente qué es lo necesario para que WCF funcione.

CREACIÓN DEL PROYECTO

Creamos un nuevo proyecto de tipo librería:

Incluimos las librerías System.ServiceModel y System.Runtime.Serialization.

EL CONTRATO (CONTRACT)

Lo primero que debemos crear es una interfaz que tendrá como misión ser el Contrato del servicio web. Lo que nos indica el mismo es qué funcionalidades tiene operativas el servicio de cara a las aplicaciones que lo van a consumir.
Creamos una interfaz llamada IService.cs y codificamos las siguientes funcionalidades:

using System.ServiceModel;
using System.ServiceModel.Web;
using System.Runtime.Serialization;

namespace WCF
{
    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        [WebGet]
        Resultado Suma(int a, int b);

        [OperationContract]
        [WebGet]
        Resultado Resta(int a, int b);
    }

   [DataContract]
    public class Resultado
   {
       [DataMember]
       public int Result { get; set; }
   }
}

Tenemos los siguientes atributos:

    * ServiceContract, el cual indica que nuestra interfaz va a hacer las veces de contrato.
    * OperationContract por cada método que queramos exponer.
    * Por último, dentro del mismo archivo (No es recomendable) hemos creado una pequeña clase con el atributo DataContract que será el objeto serializado que viajará como respuesta a las peticiones tanto de la Suma como la Resta. Por cada miembro dentro del contrato de datos, contiene un DataMember.

Es una clase perfectamente normal que contiene los métodos que definimos en el contrato. Si creamos código adicional, para realizar cualquier otra operación, no sería visible al no estar definido en la interfaz del servicio.

EL ARCHIVO SVC

Un archivo importante a tener muy en cuenta es el archivo con extensión svc, el cual erá de utilidad a IIS cuando publiquemos el servicio. Añadimos un documento en blanco, llamado Service.svc, con el siguiente contenido:

<%@ ServiceHost Service="WCF.Service" %>

Le indicamos el namespace de la  implementación del contrato como valor de Service para que pueda localizarlo.

DLL FUERA DE DEBUG Y RELEASE

Para que IIS pueda localizar correctamente las librerías del servicio web, debemos cambiar las propiedades de Build en nuestro proyecto y dejar nuestro “Output path” de la siguiente forma:

Por último, quizás la parte más compleja, necesitamos configurar el archivo web.config con los endpoints necesarios para aceptar peticiones. Dependiendo de los distintos tipos de comunicacion que tengamos, deberemos implementar más o menos endpoints.

¿Qué es un Endpoint?

Un endpoint está compuesto por tres valores: Address (¿Dónde?), Binding (¿Cómo?) y Contract (¿Qué?). La suma de ellos genera una serie de requisitos para poder establecer una conexión con nuestro servidor. Un servicio con WCF puede disponder de varios endpoints distintos, por lo que el número de clientes de diferentes características pueden consumirlo.

Creamos pues un archivo Web.config y eliminamos el contenido. En este post, voy a crear un endpoint para un cliente JSON.

<?xml version="1.0"?>
<configuration>
  <system.serviceModel>
    <bindings>
      <webHttpBinding>
        <binding name="webBinding">
        </binding>
      </webHttpBinding>
    </bindings>
    <services>
      <service name="WCF.Service"
               behaviorConfiguration="MiBehavior">
        <endpoint address="json"
                  binding="webHttpBinding"
                  bindingConfiguration="webBinding"
                  behaviorConfiguration="jsonBehavior"
                  contract="WCF.IService"/>
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="jsonBehavior">
          <enableWebScript/>
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="MiBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="True"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

Dentro de la sección system.serviceModel tenemos:

Por un lado, la sección de los bidings disponibles, que en este caso sólo tenemos el necesario para una configuración de JSON; services donde indicamos el address, el nombre de nuestro binding, el behavior (indicado más abajo)  y el nombre del contrato que queremos utilizar.

Llegados a este punto, podemos crear una aplicación que tenga hosteado el servicio que acabamos de crear o bien utilizar IIS, configurando como documento de inicio Service.svc.

IMPLEMENTACIÓN DEL CONTRATO

El siguiente paso es crear una clase que implemente el contrato que acabamos de definir.

namespace WCF
{
    public class Service : IService
    {
        public Resultado Suma(int a, int b)
        {
            var resultado = new Resultado {Result = a + b};
            return resultado;
        }

        public Resultado Resta(int a, int b)
        {
            var resultado = new Resultado {Result = a - b};
            return resultado;
        }
    }
}

Si accedemos a las dos direcciones que indico abajo a través del explorador, debería devolvernos un archivo en formato JSON por cada petición.

http://localhost/WCF/Service.svc/json/Suma

http://localhost/WCF/Service.svc/json/Resta

Ambas devolverían cero porque no se les está pasando ningún parámetro.
En el siguiente post de WCF, crearé un cliente que realice y reciba la respuesta con JSON para poder acceder a nuestro servicio web y pasarle los parámetros necesarios.

¡Saludos!

Extension Methods

Una de las nuevas funcionalidades de C# 3.0 fue la posibilidad de ampliar los métodos de una clase ya existente. Con ello, conseguimos aprovechar al máximo las clases ya predeterminadas, añadiéndole alguna funcionalidad que nos es requerida para nuestra aplicación. De no ser así, deberíamos tener estos métodos en clases distintas y perderíamos esa unificación.

He recuperado un pequeño ejemplo de msdn, donde añadimos un nuevo método a la clase String con el que podemos contar las palabras de una cadena.

Para ello, he creado un proyecto web con un texbox y un botón. Añado un proyecto de tipo librería para almacenar mi clase “Extensions” dónde especifico el nuevo método que agregaré a esta clase. De esta manera puedo utilizar mis extensiones en cualquier otro proyecto que lo necesite.

using System;

namespace Extensions
{
    public static class Extensions
    {
        public static int ContarPalabras(this String str)
        {
            return str.Split(new[] {' ', '.', '?'}, StringSplitOptions.RemoveEmptyEntries).Length;
        }
    }
}

Como podemos ver, creamos un método con el nombre que queremos que aparezca dentro de nuestra clase. Como parámetros (aquí está la clave) le indicamos que este método (this) pertenece a la clase String.
El contenido del mismo es exactamente igual que cualquier otro método. En este caso, lo único que hacemos es crearnos un array, a raíz de un split realizado a la cadena que está instanciada en nuestra clase String, y retornamos el tamaño de ese array, omitiendo los blancos.
Importamos la librería a nuestro proyecto web y, si nos creamos un String y comprobamos la lista de posibilidades nos aparecería lo siguiente:

Para comprobar esta funcionalidad, defino un evento click para mi botón y recojo la cadena introducida por el usuario para comprobar su tamaño.

using System;
using Extensions;

namespace ExtensionMethod
{
    public partial class Default : System.Web.UI.Page
    {
       protected void btnContar_Click(object sender, EventArgs e)
        {
            string cad = txtCadena.Text;
            lblResult.Text = string.Format("La cadena tiene {0} palabra(s)", cad.ContarPalabras());
        }
    }
}

¡Saludos!

¿Qué es ASP.NET MVC?

Si bien este post fue escrito en Octubre del 2009, durante la migración desde geeks.ms he ido revisando cada post publicado para intentar mejorar tanto la apariencia como las explicaciones. Por ello, voy a actualizar el contenido en cuanto a la última versión de ASP.NET MVC se refiere. ¡Empecemos!

¿Qué es MVC?

MVC significa Model View Controller y no es otra cosa que un patrón de arquitectura descrito por primera vez por Trygve Reenskaug en el año 1979.
Este patrón tiene como objetivo principal la separación de conceptos en tres capas fundamentalmente:

  • Modelo: Es la encargada del manejo de los datos de nuestra aplicación. Es decir, en ella deberíamos centrarnos en la lógica de negocio, persistencia, etcétera.
  • Vista(s): Componen la interfaz de usuario. La vista se ocupa de la representación de los datos sin contener absolutamente nada de lógica de negocio. Antes de llegar a esta capa, los datos ya han sido tratados y hay que entender los datos mostrados como un resultado de un proceso anterior (con proceso anterior me refiero a lo ocurrido en el Modelo).
  • Controlador(es): Es la capa que actúa de intermediaria entre la vista y el modelo.

¿Cómo se conectan entre ellas?

  1. Un usuario hace una petición a nuestro sitio web a través de una de las vistas. Dentro del contexto de MVC, a estas peticiones se las denominarán acciones.
  2. Esa vista contactará con su controlador y solicitará la acción requerida por el usuario.
  3. El controlador, conociendo la acción que el usuario espera, se pondrá en contacto con el Modelo para poder obtener los datos necesarios para finalizar la misma.
  4. Una vez recibimos respuesta de la capa encargada de los datos, el controlador determinará qué vista será mostrada al usuario.
  5. Por último, la vista elegida mostrará el resultado obtenido por medio del intermediario (el controlador).

Esta es una forma muy resumida y, a mi parecer, comprensible a grosso modo para conocer un poco el funcionamiento de este patrón. Si lo comparamos con Web Forms, las acciones de ASP.NET MVC serían sus eventos y la parte del Modelo la podríamos tener un proyecto aparte o bien incluir esa lógica dentro de los propios eventos como en muchas ocasiones hemos visto/hecho. Por lo tanto, gracias a la existencia de un controlador, obtenemos un desacoplamiento entre la vista y la lógica de nuestra aplicación ayudándonos por ejemplo a:

  • Un mantenimiento más efectivo del código. Por ejemplo: Si reutilizamos métodos y es necesario el cambio o la mejora del mismo solamente tendríamos que hacerlo en un único lugar.
  • Es una arquitectura óptima para realizar pruebas unitarias (TDD).
  • Conocemos en todo momento dónde está la parte de código que necesitamos manipular según su responsabilidad (No hay que buscar entre todos los eventos de todas las páginas aspx dónde puede estar duplicada la misma lógica).
  • Etcétera.

¿Cómo empiezo con ASP.NET MVC?

Para trabajar con ASP.NET MVC tenemos una serie de plantillas proporcionadas por Microsoft. Si utilizamos Visual Studio 2008, será necesario instalar dichas plantillas a través de Microsoft Web Platform Installer.

Por otro lado, desde el año 2010, ya está disponible la versión definitiva de Visual Studio 2010 donde tenemos todo lo necesario para comenzar. En este post voy a mostrarlo desde Visual Studio 2010 pero las imágenes en 2008 no difieren en absoluto a día de hoy.
Si decidimos crear un nuevo proyecto, y nos posicionamos en nuestro lenguaje preferido en el apartado Web veremos que tenemos dos plantillas para este patrón.

ASP.NET MVC 2 Web Application es una plantilla que contiene la estructura propia de MVC, pero además una serie de ejemplos para poder comprobar el funcionamiento y empezar a trabajar sobre una base. Cuando aún no tenemos conocimientos suficientes del funcionamiento de este patrón, lo ideal es comenzar a trabajar utilizando esta plantilla.

Por otro lado, ASP.NET MVC Empty Web Application apareció con la segunda versión de ASP.NET MVC debido a la gran demanda que existió a través del feedback de los desarrolladores. Es una plantilla con la estructura de MVC pero, a diferencia de la anterior, completamente limpia para comenzar a trabajar desde cero sin la necesidad de tener que eliminar ningún archivo de ejemplo.

Si creamos un proyecto con cualquiera de las dos plantillas, lo primero que nos va a preguntar es si queremos crear al mismo tiempo un proyecto paralelo para la creación de pruebas unitarias. Ese apartado se escapa del objetivo de este post por lo que vamos a obviarlo por el momento.
Una vez creado el proyecto podemos ver una estructura como la siguiente:

(Click sobre la imagen para ampliar)

Si nos damos cuenta, todos estos archivos son conocidos por todos aquellos que hayan utilizado anteriormente Web Forms solo que la organización es propia de las convenciones elegidas por Microsoft para aplicar MVC. Por ello ¡No hay que tener miedo! En los próximos post iremos viendo cada apartado y cómo interactúan entre ellos.

Espero que este artículo introductorio ayude a quitar un poco el miedo y animaros a nuevas iniciativas con ASP.NET MVC :)

¡Saludos!

Parámetros opcionales en C# 4.0

Una de las nuevas características preparadas para C# 4.0 son los parámetros opcionales, ya conocidos por Visual Basic .NET. El objetivo será declarar nuestros métodos, constructores e indexadores con unos valores por defecto en el caso de no indicarlos en la llamada. 


using System;

namespace ParametrosOpcionales
{
    class Program
    {
        static void Main()
        {
            DatosPersonales("Gisela");
            DatosPersonales("Gisela", "Perez");
            DatosPersonales("Gisela", "Perez", 10);

            Console.ReadLine();

        }

        static void DatosPersonales(string nombre, string apellido = "Torres", int edad = 20)
        {
            Console.WriteLine("Nombre:{0} Apellido:{1} Edad:{2}", nombre, apellido, edad);
        }
    }
}

Podemos realizar distintas llamadas indicando únicamente el obligatorio, el obligatorio y uno de los opcionales o todos ellos. Visto así, podemos preguntarnos cuál sería la manera de llamar a nuestro método pasándole como argumentos el primer parámetro y el último, sin querer saber nada del segundo. ¿Esto es posible? Afortunamente si y aquí es donde entran en juego los argumentos nombrados, pensados para casos como este. 


DatosPersonales(nombre: "Jose");

DatosPersonales(nombre: "Pedro", apellido: "Leal");

DatosPersonales(edad: 40, apellido: "Rodriguez", nombre: "Laura");

Si utilizamos este tipo de llamada, incluso es posible alterar el orden de los parámetros. 

Podemos llegar a pensar en la posibilidad de olvidarnos de la sobrecarga en algunos casos, sobre todo por el ahorro de código que esto supone. También es cierto que podemos necesitar que la sobrecarga y los parámetros opcionales convivan.


using System;
namespace ParametrosOpcionales
{

    class Program
    {
        static void Main()
        {
            ejemplo("Hola");

            Console.ReadLine();
        }

        static void ejemplo(object saludo)
        {
            Console.WriteLine("Object: {0}", saludo);
        }

        static void ejemplo(string saludo, string nombre = "Gisela")
        {
            Console.WriteLine("{0} {1}", saludo, nombre);
        }

        static void ejemplo(string saludo)
        {
            Console.WriteLine("Simplemente {0}", saludo);

        }
    }
}

En este ejemplo, existen tres tipos de sobrecarga. Si nosotros únicamente pasamos como argumento un string (“Hola”) debemos tener claro cual de los tres métodos será el candidato. Hay que tener en cuenta lo siguiente:

- Siempre se eligirá en primer lugar aquel método que no necesite convertir el dato que le estamos pasando a otro tipo.

- Tendrá preferencia aquel método que no necesite omitir sus parámetros opcionales.

Así pues, si arrancamos este ejemplo comprobaremos que la sobrecarga elegida será la tercera por ser el arguménto del mismo tipo y por no contenter parámetros opcionales que no se están teniendo en cuenta en nuestra llamada.

¡Saludos!

SQL Server 2008 me impide modificar mis tablas

Cuando estamos diseñando las tablas de nuestra base de datos, es posible que necesitemos modificar la estructura de las mismas una vez creadas (Añadir claves primarias, modificar el nombre de las columnas, etcétera).

En SQL Server 2008 existe una protección, habilitada por defecto, para prevenir modificaciones en las tablas que ya han sido creadas. Si intentamos hacer cualquier cambio, al querer salvarlo,  nos aparecerá el siguiente mensaje:

Prevent save changes

“No se permite guardar los cambios. Los cambios que ha realizado
requieren que se quiten y vuelvan a crear las siguientes tablas. Quizá
ha realizado cambios en una tabla que no se puede volver a crear o ha
habilitado la opción Impedir guardar cambios que requieran volver a
crear tablas.”

Para deshabilitar esta protección vamos a Tools  => Options… y en el apartado Designers deshabilitamos el checkbox  “Prevent saving changes that require table re-creation”.

Prevenir el salvado de cambios que requieren re creacion

Espero que sea de utilidad :) ¡Saludos!