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.

miércoles, 29 de abril de 2015

Preguntas de Entrevista .NET - Parametros por valor o referencia?

Si bien esta pregunta apunta a ver si tenemos los conocimientos mínimos sobre el lenguaje, es una de las que mas falla tiene a la hora de las preguntas y respuestas en una entrevista para el puesto de programador .NET. Y por que tantas fallas? bueno yo imagino que a la hora de aprender aprendieron lo que dice los libros textual y no fueron mas allá. La mayoría de las veces que vi a gente con muchos años de experiencia no saber cual seria el valor del output luego de llamar a un método.
Mi idea acá es con tres sencillos métodos aclarar un poco esta cuestión.

Quien es quien para el framework?

Vamos a aclarar cuales son las diferencias entre un parámetro que ingresa por valor y por referencia.  Según lo que podemos leer en miles de libros que andan dando vuelta o incluso en miles de blogs en la web un parámetro por valor es aquel que a un determinado método ingresa una copia del valor, en pocas palabras si nuestra variable contiene el valor 3 (utilice un int por un motivo especial) cuando llamamos a un método el framework genera una copia del valor de la variable y se lo pasa como parámetro al método. Esto es sin mas un parámetro que ingresa por valor, cual es la ventaja? la primera la velocidad, ya que estas variables se encuentran en el sector de memoria conocido como heap, con lo cual utilizan mucha menos memoria y el acceso es mas rápido. porque utilice un valor numérico para mi ejemplo? bueno básicamente porque los llamados tipos base mas los structs se alojan en el heap con lo cual siempre ingresan en un método por valor.

static void IncrementaValor(int a)
{
     a++;
     Console.WriteLine("El valor incrementado en el metodo: {0}", a);
}

En el ejemplo que vimos recién tenemos un método que recibe un número por parámetro, lo incrementa y lo muestra por pantalla. Cuando termina la ejecución por pantalla vemos al número que pasamos por valor incrementado. Ahora que pasa con nuestra variable fuera del método, la realidad es que como el framework paso una copia de nuestro valor nuestra variable quedo inmutable y conserva el valor previo a ingresar al método y eso lo podemos verificar con la siguiente prueba.

var num2 = 2;
Console.WriteLine("El valor de num2 antes de llamar al metodo: {0}", num2);
IncrementaValor(num2);
Console.WriteLine("El valor de num2 despues de llamar al metodo : {0}", num2);

Los parámetros por valor nunca se modifican?

Bueno esta es una pregunta capciosa, la realidad es que si podemos modificarlo haciendo una pequeña modificación a nuestro método.

static void IncrementaValor(ref int a)
{
     a++;
     Console.WriteLine("El valor incrementado en el metodo: {0}", a);
}

Como podemos ver ahora nuestro método tiene un modificador en el parámetro que es la palabra reservada ref la misma nos permite decirle al framework que nuestra variable queremos que entre al método por referencia, es decir en lugar de hacer una copia del valor queremos que una referencia a nuestra variable sea enviada así podemos modificar el valor interno de la misma. Esto lo podemos comprobar fácilmente con el siguiente código.

var num2 = 2;
Console.WriteLine("El valor de num2 antes de llamar al metodo: {0}", num2);
IncrementaValor(num2);
Console.WriteLine("El valor de num2 despues de llamar al metodo : {0}", num2);

Y qué parámetros son por referencia?

Bueno para concluir con esta pregunta los parámetros que ingresan a los métodos por referencia (sin necesidad de utilizar la palabra reservada ref) son los objetos en general. Siempre que pasamos como parámetro un objeto este ingresa al método por referencia. Dicho esto, cada vez que modifiquemos algo de un objeto en un método cuando termine el ámbito de ejecución del método nuestro cambio va a seguir ahi.

public class Numero
{
    public int Valor { get; set; }
}

static void IncrementaValor(Numero num)
{
     num.Valor++;
     Console.WriteLine("El valor incrementado en el metodo: {0}", num.Valor);
}

En la modificación que hice al método anterior podemos ver que enviamos un objeto y en la validación vemos que el cambio tiene efecto al salir del método.

var num2 = new Numero();
Console.WriteLine("El valor de num2 antes de llamar al metodo: {0}", num2.Valor);
IncrementaValor(num2);
Console.WriteLine("El valor de num2 despues de llamar al metodo : {0}", num2.Valor);

La idea de esta pregunta es ver si sabemos los conceptos básicos del framework, como funciona internamente y si principalmente hemos ido mas allá del concepto general de los libros o la web.

martes, 28 de abril de 2015

Preguntas de Entrevista .NET - Qué es Generics?

Bueno continuando con la serie de entradas dedicadas a analizar las preguntas que suelen aparecer en una entrevista para un puesto de desarrollador .NET. La pregunta que voy a intentar responder es la que aparece en casi todas las entrevistas en las que participe y es "Qué es Generics?". Lo primero que se nos viene a la cabeza a la hora de pensar en Generics es las colecciones. Y no esta mal que pensemos eso ya que siempre que se habla de Generics se lo asocia directamente a las listas genéricas que si, utilizan Generics pero no son el concepto de Generics en si mismas.

Entonces, qué es Generics?

Bueno la respuesta es verdaderamente muy sencilla. Generics es una herramienta que nos brinda el framework para separar el comportamiento del tipo de datos. Veamos un ejemplo sencillo que nos va a ayudar a ver mas claramente esto. Supongamos que tenemos la siguiente clase con un método estático que nos retorna cuando dos strings son iguales.

class check
{
    public static bool Compare(string a, string b)
    {
        return a.Equals(b);
    }

}

Como podemos ver es una clase muy sencilla pero si miramos en detalle vemos rápidamente que hay un problema. Este método solo nos sirve para comparar strings, con lo cual si quisiéramos comparar otro tipo de datos deberíamos sobre cargar el método Compare tantas veces como tipos de datos deseados. Y si bien esto funciona como podemos ver el código no queda limpio y el mantenimiento de esto es muy tedioso.

class check
{
    public static bool Compare(string a, string b)
    {
        return a.Equals(b);
    }
    public static bool Compare(int a, int b)
    {
        return a.Equals(b);
    }

    public static bool Compare(DateTime a, DateTime b)
    {
        return a.Equals(b);
    }
}

Entonces existe otra forma de hacer esto de una manera mas "genérica"? 

Si claro, podríamos definir nuestro tipo de dato como object. Y si esto es valido pero nos genera una sobrecarga de boxing y unboxing innecesaria. Para este tipo de cuestiones donde nosotros queremos separar el comportamiento del tipo de dato. Como hacemos estos? bueno lo primero que tenemos que hacer es definir el tipo de dato genérico que vamos a utilizar en nuestro método y eso lo hacemos utilizando los símbolos de < y > definiendo el tipo de dato adentro (generalmente se utiliza la letra T) pero cabe aclarar que podemos poner cualquier identificador ahi como podemos ver en el siguiente código.

class check
{
    public static bool Compare<UNKNOWTYPE>(UNKNOWTYPE a, UNKNOWTYPE b)
    {
        return a.Equals(b);
    }
}

Ahora que tenemos definido nuestro método de manera genérica vamos a ver como tendríamos que invocarlo.

Console.WriteLine("comparo numeros: " + check.Compare<int>(1,2));
Console.WriteLine("comparo strings: " + check.Compare<string>("hola", "hola"));

Como podemos ver ahora nuestro método sin necesidad de cambiarlo funciona con cualquier tipo de datos. Algo importante de aclarar es que el tipo de dato que utilicemos al momento de invocar nuestro método debe ser el mismo de los paramentros (porque así lo definimos). Si hubiéramos querido tipos de datos distintos lo deberíamos haber aclarado en la declaración de nuestro método. Les dejo la prueba con multiple tipos de datos genéricos a ustedes.
Entonces cuando nos encontremos con esta pregunta en una entrevista sin dudarlo debemos explicar que Generics nos brinda la posibilidad de separar nuestro comportamiento del tipo de dato, y esto lo podemos hacer a nivel de clase o de método.

Preguntas de Entrevista .NET - Diferencia entre var y dynamic

Voy a empezar a escribir una serie de entradas y esta es la primera sobre las preguntas frecuentes que nos podemos encontrar en una entrevista de trabajo cuando aplicamos para posiciones de desarrollador .NET. Estas entradas van a estar orientadas a explicar los conceptos que los entrevistadores suelen preguntar y que es lo que esperan como respuesta. Muchas veces nos parece que las preguntas no tienen sentido o creemos que son funcionalidad que no se suelen utilizar. Sin embargo es bueno saber que cuando el entrevistador hace la pregunta es porque esta esperando un conocimiento de nuestra parte. Sin mas preámbulos vamos a tema que voy a hablar en esta entrada.

Diferencias entre VAR y Dynamic


Para los que no están familiarizados con el tema los keywords VAR y Dynamic nos brindan la posibilidad de no definir el tipo de dato que vamos a utilizar al momento de declarar nuestras variables. De esta manera nuestra declaración de variables quedaría así:

var x = "string";
dynamic y = "string";

Si comparamos estas dos variables vamos a obtener como resultado que ambas son strings y que ambas contienen la palabra "string".

Ahora si ambas me dan como resultado el mismo tipo de objeto, para que existen dos palabras reservadas que hacen lo mismo? bueno la respuesta rápida a esta pregunta es que parece que hacen lo mismo pero no lo hacen.
Como es esto? bueno es sencillo, la principal diferencia entre ambas es cuando se acoplan al tipo de datos, y esto es uno de los puntos mas importantes que marca, a mi entender, la mayor ventaja de dynamic sobre var. 
Cuando declaramos una variable utilizando la palabra reservada var esta debe ser inicializada en ese mismo momento. por que? bueno la respuesta es por lo que estuvimos hablando antes, var se acopla al tipo de datos en tiempo de codificación con lo cual una vez que inicializamos la variable la misma queda asociada al tipo de datos con el que la estamos asociando. Por mas que de la impresión de que no estamos poniendo el tipo de datos si lo estamos haciendo y nuestro código sigue siendo fuertemente tipado, y no vamos a poder guardar en esta variable otra cosa que no sea lo que guardamos cuando la declaramos. 
Por otro lado, cuando declaramos una variable utilizando dynamic no es necesario que la inicialicemos para que funcione. porque esto? porque dynamic se acopla al tipo de datos en tiempo de ejecución utilizando reflection. Como podrán imaginar una de las mayores ventajas de dynamic es que convierte a nuestra variable en débilmente tipada. Esto quiere decir que el código que pongo a continuación es perfectamente valido.

dynamic y = "string";
Console.WriteLine("Contiene: {0}", y);
y = 1;
Console.WriteLine("Contiene: {0}", y);

Una de las mayores ventajas que nos da dynamic es la flexibilidad como pudimos ver recién, sin embargo una de las desventajas es la que tienen la mayoría de los lenguajes débilmente tipados y es que podemos cometer un error al llamar alguna método o bien no saber que esta almacenado en la variable. Al utilizar reflection no nos damos cuenta del error hasta que la aplicación esta ejecutando.
La ventaja que nos dar la utilización de var es que muchas veces la inicialización de una variable es una sentencia larga que suele ser tedioso y poco vistoso repetir o simplemente no sabemos cual es el tipo de datos ya que la inicialización es el resultado de una ejecución de LINQ. En esos casos la utilización de var es una manera rápida y declarar variables.

Para concluir, lo que busca un entrevistador con esta pregunta es ver cuanto conocemos del framework y cuanto utilizamos del mismo o si solo respondemos porque lo vimos así en algún lado y hacemos las cosas de manera automática.