2013-03-31 48 views
4

我被困在試圖讓下面幾行工作的東西,這裏是一個完整的代碼示例,可以在Visual Studio中運行,演示我正在談論的場景。當我改變播放器的IsReady值時,這裏的一切都按預期工作,附加到事件的lambda被觸發,並且(如果)評估爲true。然而,Console.WriteLine從來沒有命中,因爲看起來ConcurrentBag中播放器的IsReady值沒有更新。與LINQ和對象引用相關的問題

class Program 
{ 
    public static ConcurrentBag<Player> Players { get; set; } 
    static void Main(string[] args) 
    { 
     Players = new ConcurrentBag<Player>(); 
     Player player = new Player() { Id = "123" }; 
     Players.Add(player); 
     player.IsReady.ValueChanged += (from, to) => 
     { 
      if (to) 
      { 
       if (Players.All(p => p.IsReady.Value)) 
       { 
        Console.WriteLine("It worked"); 
       } 
      } 
     }; 

     LookupPlayerById("123").IsReady.Value = true; 
    } 

    public static Player LookupPlayerById(string clientId) 
    { 
     var player = Players.FirstOrDefault(x => x.Id == clientId); 
     return player; 
    } 
} 

public class Player 
{ 
    public string Id { get; set; } 
    public MonitoredValue<bool> IsReady { get; set; } 

    public Player() 
    { 
     IsReady = new MonitoredValue<bool>(false); 
    } 
} 

public class MonitoredValue<T> 
{ 
    public delegate void ValueChangedHandler(T from, T to); 
    public event ValueChangedHandler ValueChanged; 

    private T m_Value; 
    public T Value 
    { 
     get { return m_Value; } 
     set 
     { 
      if (ValueChanged != null) // if invocation list is not empty, fire the event 
      { 
       ValueChanged(m_Value, value); 
      } 
      m_Value = value; 
     } 
    } 

    public MonitoredValue() { } 

    public MonitoredValue(T initialValue) 
    { 
     m_Value = initialValue; 
    } 
} 
+1

'Player'是'class'或一個'struct'? –

+0

玩家是一個類 –

+2

然後你返回一個'參考'到Player對象。改變它的狀態將影響同一個對象,從'ConcurrentBag '被存儲的鏈接 –

回答

3

的問題是,你先通知你的聽衆,然後真正改變值。 更改屬性定義如下代碼:

delegate {}如果違約事件的實現,現在我不需要每次調用前檢查null)

public event ValueChangedHandler ValueChanged = delegate {}; 

public T Value 
{ 
    get { return m_Value; } 
    set 
    { 
     //first change 
     m_Value = value; 

     //now notify 
     ValueChanged(m_Value, value); 

    } 
} 
+0

嗯,我剛剛運行了您的代碼,發現它的行爲與預期相同。可能是我正在丟失的MonitoredValue發生了什麼 –

+0

請查看我更新的代碼示例以查看重新創建問題的完整解決方案 –

+0

@JesseCarter解決了您的問題。對我來說''它工作'' –

0

既然是引用類型,玩家將通過FirstOrDefault返回,對象引用,除非它是默認的,這種情況下,你沒有得到匹配。

例子來說明:

public static void Main() 
    { 
     ConcurrentBag<ClassA> test = new ConcurrentBag<ClassA>(); 
     var hurp = new ClassA(); 
     hurp.number = 3; 
     test.Add(hurp); 

     var derp = test.FirstOrDefault(); 
     derp.number = 4; 

     Console.Write(test.FirstOrDefault().number); 
     Console.WriteLine(derp.number); 
     Console.ReadLine(); 
    } 

打印: 44

+0

對於類爲「null」的「默認」,所以他的代碼在這種情況下會炸燬,就像你的代碼一樣。 –

+0

確實,但我假設他確實在他的收藏中擁有實體。 –