Wiem, że pojawiło się wiele postów na ten temat, ale nadal mnie to dezorientuje, dlaczego miałbyś przekazywać interfejs taki jak IList i zwracać interfejs taki jak IList z powrotem zamiast konkretnej listy.
Czytałem wiele postów mówiących, jak to ułatwia późniejszą zmianę implementacji, ale po prostu nie do końca rozumiem, jak to działa.
Powiedz, czy mam tę metodę
public class SomeClass
{
public bool IsChecked { get; set; }
}
public void LogAllChecked(IList<SomeClass> someClasses)
{
foreach (var s in someClasses)
{
if (s.IsChecked)
{
// log
}
}
}
Nie jestem pewien, jak korzystanie z IList pomoże mi w przyszłości.
A jeśli już jestem w metodzie? Czy nadal powinienem używać 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());
}
}
}
Co teraz otrzymam za używanie IList?
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;
}
A teraz? Czy jest jakaś nowa implementacja listy int, którą będę musiał zmienić?
Zasadniczo muszę zobaczyć kilka rzeczywistych przykładów kodu pokazujących, jak użycie IList rozwiązałoby jakiś problem, po prostu biorąc List do wszystkiego.
Po przeczytaniu wydaje mi się, że mogłem użyć IEnumberable zamiast IList, ponieważ po prostu przeglądam rzeczy.
Edycja Więc bawiłem się kilkoma moimi metodami, jak to zrobić. Nadal nie mam pewności co do typu zwracanego (czy powinienem uczynić go bardziej konkretnym lub interfejsem).
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;
}
Teraz zwracam IList z powodu prostego faktu, że dodam to do mojego modelu domeny, co ma taką właściwość:
public virtual IList<AvailableFeature> AvailableFeatures { get; set; }
Powyższe jest samym IListem, ponieważ wydaje się, że jest to standard używany z nhibernate. W przeciwnym razie mógłbym zwrócić IEnumberable z powrotem, ale nie jestem pewien. Mimo to nie mogę dowiedzieć się, czego użytkownik będzie potrzebował w 100% (w tym przypadku zwrot betonu ma przewagę).
Edytuj 2
Zastanawiałem się również, co się stanie, jeśli chcę przekazać przez odniesienie w mojej metodzie?
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);
}
}
}
czy miałbym z tym problemy? Ponieważ czy nie mogliby przekazać tablicy (która ma stały rozmiar)? Czy byłoby lepiej może dla konkretnej listy?