2012-03-23 3 views
1

Я пытаюсь найти лучший способ обновить объект, который может быть в одном из нескольких различных списка/коллекциилучший способ обновить объект в одном из многих списков

Пример:

public class MyItem 
{ 
    public Guid Id { get; set; } 
    public string Name { get; private set; } 
    public string Status { get; private set; } 

    public MyItem(string name) 
    { 
     this.Id = new Guid(); 
     this.Name = name; 
    } 

    public void UpdateStatus(string status) 
    { 
     this.Status = status; 
    } 
} 

public class OtherClass 
{ 
    public ObservableCollection<MyItem> ItemList1; 
    public ObservableCollection<MyItem> ItemList2; 
    public ObservableCollection<MyItem> ItemList3; 

    public UpdateStatus(Guid id, string status) 
    { 
     // Figure out which ItemList needs to be updated 
     var item = ItemList1.FirstOrDefault(s => s.Id == id); 
     if (item == null) 
     { 
      item = ItemList2.FirstOrDefault(s => s.Id == id); 
      if (item == null) 
      { 
       item = ItemList3.FirstOrDefault(s => s.Id == id); 
       if (item == null) 
       { 
        Debug.WriteLine("Unable to update Status"); 
        return; 
       } 
      } 
     } 
     item.UpdateStatus(status); 
    } 
} 

Мне не нравится вложенный, если это так, я уверен, что есть лучший способ, но его пятница и мой мозг жарятся :(

Я понимаю, что я мог бы добавить что-то вроде этого, вместо вложенных IFS:

public MyItem UpdatedStatus(ObservableCollection collection, Guid id) 
{ 
    return collection.FirstOrDefault(s => s.Id == id); 
} 

или

public bool UpdatedStatus(ObservableCollection collection, Guid id, string status) 
{ 
    var item = collection.FirstOrDefault(s => s.Id == id); 
    if (item != null) 
    { 
     item.UpdateStatus(status); 
     return true; 
    } 
    return false; 
} 

Но мне кажется, что там должно быть лучше

Любые советы?

Эти коллекции могут содержать сотни элементов в них с более поздними, поэтому я пытаюсь найти наиболее эффективный способ обработки обновлений.

+0

Пожалуйста, не прикрепите свои заголовки к «C#» и тому подобное. Для этого нужны теги. –

ответ

3

LINQ для помощи. Он работает для вас, как и ожидалось?

var item = ItemList1.Union(ItemList2) 
        .Union(ItemList3) 
        .FirstOrDefault(s => s.Id == id); 

Важно:

Union() возвращает уникальные элементы, это может быть медленным на больших наборов данных, поэтому рекомендуется использовать Concat() для больших списков вместо»

var item = ItemList1.Concat(ItemList2) 
        .Concat(ItemList3) 
        .FirstOrDefault(s => s.Id == id); 

Также стоит принять взглянуть на Jon Skeet's Concat() реализация от edulinq serie, Concat() действительно проста: (Full Article)

private static IEnumerable<TSource> ConcatImpl<TSource>( 
    IEnumerable<TSource> first, 
    IEnumerable<TSource> second) 
{ 
    foreach (TSource item in first) 
    { 
     yield return item; 
    } 
    foreach (TSource item in second) 
    { 
     yield return item; 
    } 
} 
+0

Разве Союз не заберет наибольшее количество времени, так как он объединит все коллекции в один? Или он будет искать их по порядку? – John

+0

'Union()' выполняет сравнение элементов для возврата уникальных результатов, поэтому пока он будет относительно медленным. Но для небольших наборов данных эта разница может быть проигнорирована. если вам нужно более эффективное решение - используйте LINQ 'Concat()' – sll

+0

Задача, заданная в вопросе, не требует использования 'Union'. 'Concat' с' FirstOrDefault' будет делать то же самое, что и код в вопросе. –

3

Вы можете использовать null-coalescing operator (??), чтобы упростить код:

public UpdateStatus(Guid id, string status) 
{ 
    var item = ItemList1.FirstOrDefault(s => s.Id == id) 
     ?? ItemList2.FirstOrDefault(s => s.Id == id) 
     ?? ItemList3.FirstOrDefault(s => s.Id == id) 
    if (item == null) 
    { 
     Debug.WriteLine("Unable to update Status"); 
     return; 
    } 
    item.UpdateStatus(status); 
} 
+0

Человек за то, сколько тройных операций я сделал с нулевыми проверками, это бы упростило его :) – John

Смежные вопросы