Я знаю, что по этому поводу было много сообщений, но меня все еще смущает, почему вы должны передавать интерфейс, такой как IList, и возвращать интерфейс, такой как IList, вместо конкретного списка.
Я читал много сообщений, в которых говорилось, что это упрощает изменение реализации позже, но я просто не совсем понимаю, как это работает.
Скажите, есть ли у меня этот метод
public class SomeClass
{
public bool IsChecked { get; set; }
}
public void LogAllChecked(IList<SomeClass> someClasses)
{
foreach (var s in someClasses)
{
if (s.IsChecked)
{
// log
}
}
}
Я не уверен, как использование IList поможет мне в будущем.
Как насчет того, чтобы я уже участвовал в методе? Следует ли мне по-прежнему использовать 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());
}
}
}
Что я получу за использование 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;
}
Как насчет сейчас? Есть ли какая-то новая реализация списка int, который мне нужно будет изменить?
По сути, мне нужно увидеть несколько реальных примеров кода, показывающих, как использование IList решило бы некоторые проблемы, связанные с простым включением List во все.
Из моего чтения я думаю, что мог бы использовать IEnumberable вместо IList, поскольку я просто просматриваю материал.
Редактировать Итак, я экспериментировал с некоторыми из моих методов, как это сделать. Я до сих пор не уверен в возвращаемом типе (нужно ли сделать его более конкретным или интерфейсом).
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;
}
Теперь я возвращаю IList из-за того простого факта, что затем я добавлю это в свою модель домена, у которой есть такое свойство:
public virtual IList<AvailableFeature> AvailableFeatures { get; set; }
Вышеупомянутое является самим IList, поскольку это то, что кажется стандартом для использования с nhibernate. В противном случае я мог бы вернуть IEnumberable, но не уверен. Тем не менее, я не могу понять, что на 100% понадобится пользователю (в этом случае возврат бетона имеет преимущество перед).
Редактировать 2
Я также думал, что произойдет, если я захочу выполнить передачу по ссылке в моем методе?
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);
}
}
}
у меня возникнут проблемы с этим? Поскольку они не могли передать массив (имеющий фиксированный размер)? Может быть, лучше для конкретного списка?