2012-02-01 86 views
0

我有幾雙從一本詞典移動元素到另一個

Dictionary<DateTime, ObservableCollection<Car>> 

,我改變生產Car的一年,因爲KeyDateTime)詞典是一年,我需要移動這CarKeyValuePair與舊的一年到KeyValuePair與新的一年。

因此,例如,我有兩個對:

1.1.1997 {Car1,Car2} 
1.1.1998 {Car3} 

Car2.Production = Convert.ToDateTime("1.1.1998"); 

我需要有

1.1.1997 {Car1} 
1.1.1998 {Car3,Car2} 

什麼是實現這一目標的最簡單的方法?

+2

不確定有任何* easy *方法可以做到這一點。您可能需要重新考慮使用生產年份的'DateTime'作爲'Dictionary'中的'Key'。如果這是一個數據庫,你會引入一個非常討厭的函數依賴。 – Yuck 2012-02-01 15:55:25

+0

我知道存在代碼異味,但我沒有太多時間來重構這個。我需要使用該代碼。 – user278618 2012-02-01 15:56:43

+0

您是否有權訪問代碼區中的'Dictionary >',在這個代碼區中,您要提取個別'Car'來修改其「Production」值? – Yuck 2012-02-01 15:59:40

回答

2

看起來你可能想爲這些數據使用分組視圖,但是這裏有一個解決問題的代碼解決方案。如果您打算爲多個屬性執行此操作,我建議將Car從DependencyObject繼承或從INotifyPropertyChanged實現,而不是爲每個屬性創建事件。

// The car class itself 
public class Car 
{ 
    // This event is raised when the production property changes 
    public event EventHandler<PropertyValueChange<DateTime>> ProductionChanged; 
    DateTime _production; // private data 
    public DateTime Production 
    { 
     get { return _production; } 
     set 
     { 
      if (value == _production) return; // don't raise the event if it didn't change 
      var eventArgs = new PropertyValueChange<DateTime>(_production, value); 
      _production = value; 
      // If anyone is "listening," raise the event 
      if (ProductionChanged != null) 
       ProductionChanged(this, eventArgs); 
     } 
    } 
} 
// Class that contains the dictionary of production to car lists 
class Foo 
{ 
    Dictionary<DateTime, ObservableCollection<Car>> ProductionToCars = new Dictionary<DateTime, ObservableCollection<Car>>(); 

    public void Add(Car c) 
    { 
     _Add(c); 
     // We want to be notified when the car's production changes 
     c.ProductionChanged += this.OnCarProductionChanged; 
    } 
    // This is called when a car's value changes, and moves the car 
    void OnCarProductionChanged(object sender, PropertyValueChange<DateTime> e) 
    { 
     Car c = sender as Car; 
     if (c == null) return; 
     ProductionToCars[e.OldValue].Remove(c); 
     _Add(c); 
    } 
    // this actually places the car in the (currently correct) group 
    private void _Add(Car c) 
    { 
     ObservableCollection<Car> collection; 
     // Find the collection for this car's year 
     if (!ProductionToCars.TryGetValue(c.Production, out collection)) 
     { 
      // if we couldn't find it, create it 
      collection = new ObservableCollection<Car>(); 
      ProductionToCars.Add(c.Production, collection); 
     } 
     // Now place him in the correct collection 
     collection.Add(c); 
    } 

} 
// This class encapsulates the information we'll pass when the property value changes 
public class PropertyValueChange<T> : EventArgs 
{ 
    public T OldValue; 
    public T NewValue; 
    public PropertyValueChange(T oldValue, T newValue) 
    { 
     OldValue = oldValue; 
     NewValue = newValue; 
    } 
} 
1

這應該工作(不是最短的代碼可能的,但簡單的理解):

private static void EnsureValuesAreCoherent(Dictionary<DateTime, ObservableCollection<Car>> param) 
{ 
    List<Car> toMove = new List<Car>(); 
    foreach (KeyValuePair<DateTime, ObservableCollection<Car>> pair in param) 
    { 
     List<Car> toRemove = new List<Car>(); 
     foreach (Car car in pair.Value) 
     { 
      if (car.Production != pair.Key) 
      { 
       toRemove.Add(car); 
      } 
     } 

     foreach (Car car in toRemove) 
     { 
      pair.Value.Remove(car); 
      toMove.Add(car); 
     } 
    } 

    foreach (Car car in toMove) 
    { 
     ObservableCollection<Car> currentCollection; 
     if (param.TryGetValue(car.Production, out currentCollection)) 
     { 
      currentCollection.Add(car); 
     } 
    } 
} 

但IMO這是一個壞主意,有字典中的一員字典的鍵之間的這種相關性,值。

1

你需要在這種情況下有一個詞典?如果需求者希望能夠在特定生產日期的所有車輛上運行,您是否可以不使用Linq?

ObservableCollection<Car> cars = new ObservableCollection<Car>(); 
var car1 = new Car() { Model = "Ford", ProductionDate = new DateTime(1997, 01, 01)}); 
var car2 = new Car() { Model = "Chevy", ProductionDate = new DateTime(1997, 01, 01)}); 
var car3 = new Car() { Model = "Ford", ProductionDate = new DateTime(2002, 01, 01)}); 
cars.Add(car1); 
cars.Add(car2); 
cars.Add(car3); 

var carsIn1997 = cars.Where(x => x.ProductionDate.Year == 1997); 
var carsThatAreFords = cars.Where(x => x.Model == "Ford"); 
var groupedCars = cars.GroupBy(x => x.ProductionDate); 

使用這種方法,你可以訪問所有的汽車在一個特定的年份,型號等...和操縱數據,而不用擔心周圍等移動引用...

對於一般的GroupBy教程,請參閱here

相關問題