martes, 12 de mayo de 2015

Preguntas de Entrevista .NET - Diferencias entre Abstract Class e Interface

Esta pregunta es uno de los clásicos en las entrevistas para desarrollador .NET. Lo que quiero decir con esto es que no hay entrevista sin esta pregunta. Es muy importante que podamos enumerar claramente las diferencias entre ambos, explicar los conceptos que hay detrás de cada una de estas diferencias, conceptos teóricos y practico de la implementación. Y por ultimo que podamos emitir una opinion sobre cual utilizar en que momento y porque.

Qué es una Abstract Class ?


Lo primero que deberíamos hacer es explicar con claridad cual es el concepto de Abstract Class, estas son clases que brindan un contracto para que las clases que derivan de estas sigan. Lo que quiere esto decir es que en una clase abstracta vamos a definir un marco para las clases que de esta deriven, definiendo funcionalidad (la cual puede ser sobrescrita o definiendo contratos que deben ser implementados. Cabe destacar que de una clase abstracta no se puede crear una instancia con lo cual para acceder a su funcionalidad debemos derivar de esta en una clase no abstracta.
En principio existen dos formas de declarar funcionalidad en una clase abstracta como podemos ver en el código que esta a continuación.

    public abstract class Vehiculo
    {
        virtual public string Andar()
        {
            return "Estoy funcionando";
        }

        abstract public string Frenar();
    }

    public class Automovil : Vehiculo
    {
        public override string Frenar()
        {
            return "Acabo de frenar";
        }
    }

Como podemos ver declaramos en nuestra clase abstracta dos métodos, uno utilizando la palabra reservada virtual, con esto lo que hacemos es definir un método que tiene un comportamiento básico definido pero deja la puerta abierta a que la clase que deriva de esta puede sobre escribir este comportamiento. Y otro método que utiliza la palabra reservada abstract que como se puede ver no tiene comportamiento definido y con esto lo que hacemos es definir un contracto que debe ser implementado en la clase que deriva como se muestra en el ejemplo anterior. De esta manera salen a la luz dos de las formas en las que podemos utilizar una clase abstracta y es para definir comportamiento o para definir un contracto.
Existe algo que debe ser remarcado en este punto que las clases abstractas se rigen por las reglas de la herencia con lo cual una clase solo puede heredar de una clase abstracta (o no) y no mas de una clase.

Qué es una Interface?


Las interfaces son un recurso que nos brinda el framework para definir contratos que deben ser definidos por las clases que implementan dichas interfaces. Cabe destacar que una interface no define comportamiento, el mismo si o si debe ser definido en las clases que la implementan. Las clases que implementan una interface deben definir comportamiento para todos los miembros de la interface. Como las interfaces no son clases una clase puede implementar cuantas interfaces se desee como se puede ver en el ejemplo siguiente.

    public interface IDibujar
    {
        string Dibujar();
        string Definir();
    }

    public interface IDibujarHexagono
    {
        string Dibujar();
    }

    public class Hexagono : IDibujar, IDibujarHexagono
    {

        string IDibujar.Dibujar()
        {
            return "Implementacion del metodo Dibujar";
        }

        public string Definir()
        {
            return "Implementacion del metodo Definir";
        }

        string IDibujarHexagono.Dibujar()
        {
            return "Implementacion del metodo Dibujar Vertices";
        }
    }

Se puede ver nuestra clase implementa dos interfaces distintas. Algo que hablando de clases no se puede hacer ya que sabemos que en C# esta prohibido la herencia multiple. Otro punto clave que podemos ver en este ejemplo es que se puede hacer un llamado explícito de que interface estamos definiendo que método. Podemos ver que el método Dibujar esta definido en dos interfaces distintas que nuestra clase Hexagono esta implementando. Por este motivo estamos explicando de que interface estamos definiendo que método. Para poder utilizar uno u el otro deberíamos hacerlo mediante el uso de cast para cada interface. La forma en la que se utiliza lo podemos ver en el siguiente ejemplo.

            var hexa = new Hexagono();

            IDibujar test1 = (IDibujar) hexa;
            Console.WriteLine(test1.Dibujar());
            IDibujarHexagono test2 = (IDibujarHexagono)hexa;
            Console.WriteLine(test2.Dibujar());

Las diferencias


Habiendo explicado ambos podemos ver que ambas opciones nos ofrecer un mecanismo para definir comportamiento. Las interfaces sobre las clases abstractas nos brindan la posibilidad de implementar mas de una interface mientras que solo podemos derivar de una clase abstracta por vez. En este sentido las interfaces nos brindan mas flexibilidad a la hora de definir comportamiento. Como contrapartida sobre las interfaces podemos decir que estas son implementaciones de "todo o nada" lo que quiere decir que cuando implementamos una interface debemos definir todos los métodos que esta define. Las interfaces como bien ya dijimos a diferencia de las clases abstractas estas no definen comportamiento para los contratos que definen.

Para cerrar cabe aclarar que a la respuesta de qué conviene utilizar se puede responder que depende de las circunstancias. Por esto es importante que expliquemos cuales son los pro y contra de cada una de las herramientas y en que aspecto conviene utilizar una u otra.

viernes, 8 de mayo de 2015

Preguntas de Entrevista .NET - Qué son las variables Nullables y para que sirve?

Es común que en una entrevista para desarrollador .Net nos pregunten qué son las variables Nullables, como declararlas y para que sirven. Estas preguntas si bien no son complejas es importante hablar claramente de este tipo de variables, explicar cuales son sus beneficios y sobre todo saber como utilizarlas.


Qué problema resuelven?


Como todos saben a esta altura los value type (structs) no admiten como valor null, esto quire decir que si nosotros declaramos una variable de tipo int por ejemplo nunca vamos a poder una comparación por null ya que dicha variable no admite null como valor. Una posible solución elegante a este problema seria definir nuestra propia estructura entero que si soporte valores null como hice yo en el ejemplo a continuación.

    public struct Entero
    {
        private int _valor;
        private bool _tieneValor;

        public Entero(int valor)
        {
            _valor = valor;
            _tieneValor = true;
        }

        public int Valor
        {
            get
            {
                if (!_tieneValor)
                    throw new InvalidOperationException("No se ha definido un valor para esta variable");
                return _valor;
            }
            set
            {
                _valor = value;
                _tieneValor = true;
            }
        }

        public bool TieneValor
        {
            get { return _tieneValor; } 
        }

        public static implicit operator Entero(int valor)
        {
            return new Entero(valor);
        }

        public static Entero Null
        {
            get { return new Entero(); } 
        }
    }

Como podemos ver basicamente agregue dos propiedades a la estructura, una que nos indica la precia de valor o no y la otra el valor en si mismo. De esta manera la consulta a esta estructura seria algo así.

        static void Main(string[] args)
        {
            Entero variable = 3;
            Entero variable2 = Entero.Null;

            Console.WriteLine(variable.TieneValor? variable.Valor.ToString() : "null");
            Console.WriteLine(variable2.TieneValor ? variable2.Valor.ToString() : "null");
            Console.ReadKey();
        }

Ahora si todo muy lindo pero esto para nosotros tiene un costo altísimo, si bien esta estructura es bastante sencilla cada vez que nos ponemos a reinventar la rueda corremos el riesgo que nos quede algo cuadrada. Ahi es donde viene el Framework a salvarnos definiendo un tipo de dato Nullable, que quiere decir esto? que acepta valores null.


Como definir los tipos Nullables?


Bueno basicamente la forma de definir que nuestro tipo de dato va a soportar null es agregando el operador ? al tipo de dato que estamos especificando. De esta manera las declaración que hice recién nos quedaran así.

        static void Main(string[] args)
        {
            int? vari = 3;
            int? vari2 = null;

            Console.WriteLine(vari.HasValue ? vari.Value.ToString() : "null");
            Console.WriteLine(vari2.HasValue ? vari2.Value.ToString() : "null");
            Console.ReadKey();
        }

Ahora lo que podemos ver es que la utilización es muy parecida a lo que habíamos definido anteriormente con lo cual lo que nos estamos ahorrando es la necesidad de crear nuestro propio tipo de datos para soportar valores null. Por otro lado al utilizar valor Nullables podemos hacer uso del operador que estuvimos viendo hace unas entradas el ?? ya que Nullable<T> nos ofrece varios métodos para hacer uso de esto como podemos ver a continuación.

        static void Main(string[] args)
        {
            int? vari = 3;
            int valor = 0;
            
            valor = vari.HasValue ? vari.Value : 7;
            valor = vari.GetValueOrDefault(7);
            valor = vari ?? 7;
            Console.WriteLine(vari2.HasValue ? vari2.Value.ToString() : "null");
            Console.ReadKey();
        }

Con cualquiera de las tres opciones que mostré anteriormente podemos ver que dependiendo del valor de la variable vamos a asignar el valor que tenga o en su defecto otro valor (o valor por defecto).
Ahora luego que vimos como funciona esta clase podemos decir con seguridad cuales son sus beneficios a la hora de trabajar con variables que podrían recibir valores null para comprarlas, manipularlas y hasta como acceder a su valor. De esta manera la respuesta a esta pregunta es que variables que soportan como valor null y que nos dejan manipularlo para poder acceder al valor de la misma.

jueves, 7 de mayo de 2015

C# Avanzado - Crear un HTML helper method para sitio web con MVC framework

Dejamos un poco de lado la preguntas de entrevistas para hacer un pequeño post sobre un tema muy util a la hora de crear sitios webs utilizando MVC framework. La idea detrás de este concepto es la de crear extensiones para la clase HtmlHelper y de esta manera generar componentes compartidos en nuestro proyecto.

Crear la extensión

Para crear la extensión a la clase HtmlHelper lo primero que vamos a hacer es crear un Extension Method (pueden buscar en mi blog un post al respecto). Este método sera el encargado de crear el componente HTML que se va a mostrar en nuestro sitio web. Para este ejemplo voy a mostrar como hacer un componente HTML que genera una filtro para una lista. Este filtro no es mas que un abecedario, cada letra cuenta con un link que hará un filtro sobre una lista. Habiendo presentado esto muestro como debería quedar nuestro Extension Method.

namespace WebUI.HtmlHelpers
{
    public static class Paginator
    {
        public static MvcHtmlString PageLink(this HtmlHelper html, List<char> col, Func<char, string> GetURL)
        {
            StringBuilder result = new StringBuilder();
            TagBuilder tag = new TagBuilder("a");
            tag.MergeAttribute("href", GetURL('*'));
            tag.InnerHtml = "ALL";
            result.Append(tag.ToString());
            result.Append(" | ");
            foreach (var letter in col)
     {
                tag = new TagBuilder("a");
                tag.MergeAttribute("href", GetURL(letter));
                tag.InnerHtml = letter.ToString().ToUpper();
                result.Append(tag.ToString());
                result.Append(" | ");
     }

            return MvcHtmlString.Create(result.ToString());
        }
    }
}

Como podemos ver el method debe ser static al igual que la clase que lo contiene. El valor de retorno de nuestro método es del tipo MvcHtmlString que no es ni mas ni menos que un HTML-encoded string. Como parámetros nuestro método debe recibir (como condición para los Extension Method) al HtmlHelper, recordamos que esta es la clase donde nuestro método va a extender. El segundo parámetro como ya había mencionado anteriormente es la lista de caracteres que queremos mostrar en nuestro componente de HTML y finalmente como tercer parámetro vamos a recibir un Funk que utilizaremos para seleccionar dentro de nuestra lista y generar el componente Link, pero eso lo vamos a ver en un minuto.

Lo que vamos a hacer en este método es muy sencillo, vamos a generar mediante un string el HTML plano que queremos que nuestro componente muestre. Para esto mediante la clase TagBuilder vamos a ir generando los tags necesarios. En este caso estamos creando links pero recuerden que ustedes pueden hacer el componente que necesiten. Una vez que tengamos completo nuestro string que representa el HTML plano que queremos mostrar por pantalla llamamos al método estático Create que expone la clase MvcHtmlString para generar nuestro valor de retorno.

  
<system .web.webpages.razor="">
    <host factorytype="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
    <pages pagebasetype="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
        <add namespace="WebUI.HtmlHelpers" />
       </namespaces>
    </pages>
  </host>
</system>

Seguido a esto debemos indicarle a Razor que tenga en cuenta nuestro componente. Para hacer esto debemos incluir en el Web.Config el namespace de nuestro Extension Method para que el mismo sea accesible. Para esto solo debemos hacer lo que hice en el código que podemos ver arriba.

Utilizar nuestro metodo


Ahora que tenemos nuestro método disponible (por que lo incluimos en el Web.Config) solo debemos incluirlo en nuestra Vista y lo vamos a hacer como se muestra a continuación.
@{
    var collection = new List<char> { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o','p','q','r','s','t',
    'u','v','w','x','y','z'};
    @Html.PageLink(collection, x => Url.Action("Index", new { start = x }))
}
Como podemos ver solo debemos llamar a la clase @Html y automáticamente va a tener nuestro método. Al mismo le pasamos los parámetros que hemos definido oportunamente. Como ya había adelantado nuestro parámetro Func es una expresión Lambda para seleccionar en nuestra colección y generar el componente ActionLink.

Esta es una manera sencilla de generar componentes comunes a nuestro sitio web mediante estos HtmlHelpers. Espero que este pequeño aporte les sirva, recuerden que este es un ejemplo muy simple de lo que se puede hacer con estos Helpers pero sepan que el poder de esta herramienta esta en la construcción personalizada de componentes HTML y como ya saben cualquier duda que tengan no tienen mas que preguntar.


miércoles, 6 de mayo de 2015

Preguntas de Entrevista .NET - Diferencias entre operadores: ? y ??, & y && , | y ||, ^

Muchas veces nos encontramos en las entrevistas con las clásicas preguntas sobre los operadores lógicos y sus comportamiento. Es bueno explicar claramente para que sirve cada uno de estos y cual es su diferencia. Vamos a comenzar ahora hablando de los operadores lógicos && y || que como todos sabes representan el AND y OR condicional. Que quiere decir esto? que es un la comparación que va a realizar es la siguiente.

Comportamiento de && (AND condicional) y || (OR condicional)

Cuando utilizamos el AND condicional lo que hacemos en evaluar dos condiciones las cuales en el caso del && deben cumplirse ambas para que la condición sea verdadera. Vale aclarar como hace el framework para realizar la evaluación de las condiciones. Al utilizar el operador && el framework evaluara la primer condición y solo si es verdadera prosigue a evaluar la segunda condición. Este comportamiento genera un ahorro computacional ya que en caso de que la primer condición no se cumpla considera en ese momento que toda la condición es falsa.
En el caso del OR condicional con que una de las condiciones sea verdadera toda la condición da como resultado verdadero así que como ya explique en el caso anterior evaluar la primer condición y en caso de que sea verdadera el framework considera que es suficiente y no continua con la otra parte de la evaluación.

Comportamiento de & (AND logico) y | (OR logico)

A diferencia de los casos anteriores (cuando utilizamos los operadores simples en lugar de dobles) lo que estamos haciendo es decirle al framework que queremos que la comparación sea lógica con lo cual ambas partes de la condición va a ser evaluadas antes de resolver el resultado de la comparación. Esta es la principal característica de ambos tipos de operadores. Suelen ser utilizados con con tipos de datos int ya que poseen la capacidad de hacer un Bitwise pero también pueden ser utilizados con tipos de datos bool.

El XOR logico de la mano del ^

Existe un operador que no es muy utilizado pero sirve para realizar un evaluación de XOR lógica y es el ^. Esta evaluación solo sera considerada positiva si alguno de los dos es verdadero pero no los dos como podemos ver en el siguiente ejemplo:

if (var1 ^ var2)
{
    Console.WriteLine("Entre porque uno de los dos es falso");
}

Comportamiento del operador ?

Este operador tiene multiples usos dependiendo de donde se lo utilice. En este caso puntual nos vamos a enfocar en el uso que se le da para realizar comparaciones (mas precisamente el if inline) y la estructura que tiene es la siguiente:

var ret = var1 & var2 ? 1 + 2 : 0;

Como podemos ver el ? se utiliza para realizar la evaluación de nuestra condición. El valor que se encuentra inmediatamente después del ? es el valor que retornara nuestro if inline en caso de que la condición sea verdadera. El valor que se encuentra después del símbolo : es el valor que retornaremos en caso de que la condición sea falsa.

Comportamiento del operador ??

En este caso el operador ?? nos ofrece la posibilidad de realizar una evaluación por null. Es decir como podemos ver en el siguiente ejemplo comparamos una expresión o variable por null y nos ofrece reemplazar el valor null por otro como se ve en el ejemplo siguiente, cabe aclarar que el valor por el que vamos a reemplazar en caso de que sea null nuestra expresión debe ser igual a la expresión que estamos evaluando.

int? val = 0;
var ret = val ?? 0;

Para resumir podemos decir que las diferencias son mínimas en el caso de los operadores Lógicos y Condicionales y una diferencia de comportamiento en el caso de ? y ??. Es importante que tengamos bien en clara las diferencias para poder explicarlas de manera simple y sencilla.