Sé que ha habido muchas publicaciones sobre esto, pero todavía me confunde por qué debería pasar una interfaz como IList y devolver una interfaz como IList en lugar de la lista concreta.
Leí muchas publicaciones que dicen cómo esto hace que sea más fácil cambiar la implementación más adelante, pero no veo completamente cómo funciona eso.
Di si tengo este método
public class SomeClass
{
public bool IsChecked { get; set; }
}
public void LogAllChecked(IList<SomeClass> someClasses)
{
foreach (var s in someClasses)
{
if (s.IsChecked)
{
// log
}
}
}
No estoy seguro de cómo el uso de IList me ayudará en el futuro.
¿Qué tal si ya estoy en el método? ¿Debería seguir usando IList?
public void LogAllChecked(IList<SomeClass> someClasses)
{
//why not List<string> myStrings = new List<string>()
IList<string> myStrings = new List<string>();
foreach (var s in someClasses)
{
if (s.IsChecked)
{
myStrings.Add(s.IsChecked.ToString());
}
}
}
¿Qué obtengo por usar IList ahora?
public IList<int> onlySomeInts(IList<int> myInts)
{
IList<int> store = new List<int>();
foreach (var i in myInts)
{
if (i % 2 == 0)
{
store.Add(i);
}
}
return store;
}
¿Que tal ahora? ¿Hay alguna nueva implementación de una lista de int que tendré que cambiar?
Básicamente, necesito ver algunos ejemplos de código reales de cómo el uso de IList habría resuelto algún problema sobre simplemente incluir List en todo.
Por mi lectura, creo que podría haber usado IEnumberable en lugar de IList ya que solo estoy repasando cosas.
Editar Así que he estado jugando con algunos de mis métodos sobre cómo hacer esto. Todavía no estoy seguro del tipo de devolución (si debo hacerlo más concreto o una interfaz).
public class CardFrmVm
{
public IList<TravelFeaturesVm> TravelFeaturesVm { get; set; }
public IList<WarrantyFeaturesVm> WarrantyFeaturesVm { get; set; }
public CardFrmVm()
{
WarrantyFeaturesVm = new List<WarrantyFeaturesVm>();
TravelFeaturesVm = new List<TravelFeaturesVm>();
}
}
public class WarrantyFeaturesVm : AvailableFeatureVm
{
}
public class TravelFeaturesVm : AvailableFeatureVm
{
}
public class AvailableFeatureVm
{
public Guid FeatureId { get; set; }
public bool HasFeature { get; set; }
public string Name { get; set; }
}
private IList<AvailableFeature> FillAvailableFeatures(IEnumerable<AvailableFeatureVm> avaliableFeaturesVm)
{
List<AvailableFeature> availableFeatures = new List<AvailableFeature>();
foreach (var f in avaliableFeaturesVm)
{
if (f.HasFeature)
{
// nhibernate call to Load<>()
AvailableFeature availableFeature = featureService.LoadAvaliableFeatureById(f.FeatureId);
availableFeatures.Add(availableFeature);
}
}
return availableFeatures;
}
Ahora estoy devolviendo IList por el simple hecho de que luego agregaré esto a mi modelo de dominio que tiene una propiedad como esta:
public virtual IList<AvailableFeature> AvailableFeatures { get; set; }
Lo anterior es un IList en sí mismo, ya que parece ser el estándar para usar con nhibernate. De lo contrario, podría haber devuelto IEnumberable, pero no estoy seguro. Aún así, no puedo entender qué necesitaría el usuario al 100% (ahí es donde devolver un concreto tiene una ventaja).
Editar 2
También estaba pensando ¿qué pasa si quiero pasar por referencia en mi método?
private void FillAvailableFeatures(IEnumerable<AvailableFeatureVm> avaliableFeaturesVm, IList<AvailableFeature> toFill)
{
foreach (var f in avaliableFeaturesVm)
{
if (f.HasFeature)
{
// nhibernate call to Load<>()
AvailableFeature availableFeature = featureService.LoadAvaliableFeatureById(f.FeatureId);
toFill.Add(availableFeature);
}
}
}
¿tendría problemas con esto? ¿Ya que no podrían pasar en una matriz (que tiene un tamaño fijo)? ¿Sería mejor quizás para una lista concreta?