En su interfaz pública, generalmente debe tratar de exponer un tipo abstracto que satisfaga los requisitos de su usuario (incluso si su "usuario" es su propio código).
Debe asignar buenos valores predeterminados para estos tipos genéricos, para que pueda comenzar a utilizarlos lo antes posible en su código, en lugar de tener que crear y asignar un tipo concreto cada vez que quiera usarlo.
Un ejemplo:
public class Something
{
public Something()
{
this.Map = new Dictionary<string, string>();
}
public IDictionary<string, string> Map { get; set; }
}
Esto permite que el usuario de la clase, o el implementador, para cambiar a un nuevo tipo de diccionario sin romper el código existente, pero al mismo tiempo no requiere que el usuario escriba este código cada vez que lo utilizan:
var something = new Something();
something.Map = new Dictionary<string, string>();
se puede simplemente comenzar a usarlo:
var something = new Something();
something.Map["test"] = "some value";
Ejemplos de otros tipos:
public IEnumerable<string> ValuesReadOnly { get; private set; } // Read-only access
public IEnumerable<string> ValuesReadWrite { get; set; } // Sequence read-write access
public IList<string> ValuesRandomReadWrite { get; set; } // Random read-write access
Una buena razón para hacer esto es por lo que se puede conectar en cualquier tipo en el futuro, sin tener que convertirlo en el tipo específico que ha definido. Nada contamina el código más rápido que tener que hacer conversiones ay desde varios tipos.
Por ejemplo, encuentro que uso IEnumerable
mucho cuando uso Linq. Si tuviera List<T>
para mis miembros públicos, siempre tendría que convertir los valores en listas antes de asignarlos, lo que no solo aumenta mi código, sino que también perjudica el rendimiento. Tienes que hacer otra copia de la estructura de la lista en la memoria, y no puedes aprovechar cosas como las secuencias de evaluación diferida/yield return
.
Un ejemplo de esto:
public class Something2
{
public IEnumerable<string> SomeValues { get; set; }
}
var dbQuery = BuildQuery("select item from inventory where item.Price > 5.00");
var something = new Something();
something.SomeValues = dbQuery.Evaluate(); // Imagine if this did paging...
En lugar de:
public class Something2
{
public List<string> SomeValues { get; set; }
}
var dbQuery = BuildQuery("select item from inventory where item.Price > 5.00");
var something = new Something();
something.SomeValues = dbQuery.Evaluate().ToList(); // Has to evaluate all of them...
¿Y si algún día pronto Microsoft reemplaza Dictionary <> con SuperDuperDictionary <>, y una persona utiliza su clase no podrá para aprovecharlo? –