LINQ和对象引用的问题
本文关键字:问题 对象引用 LINQ | 更新日期: 2023-09-27 18:06:38
我一直在尝试让下面几行工作,这里是一个完整的代码示例,可以在Visual Studio中运行,演示了我正在谈论的场景。这里的一切都如预期的那样工作,当我改变玩家的IsReady值时,附加到事件的lambda被触发,if (to)计算结果为true。然而,控制台。WriteLine永远不会被击中,因为在ConcurrentBag中,玩家的IsReady值似乎没有更新。
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;
}
}
问题是您首先通知侦听器,然后才实际更改值。将属性定义更改为以下代码:
(delegate {}
如果默认事件的实现,现在我不需要检查空前每次调用)
public event ValueChangedHandler ValueChanged = delegate {};
public T Value
{
get { return m_Value; }
set
{
//first change
m_Value = value;
//now notify
ValueChanged(m_Value, value);
}
}
因为它是一个引用类型,Player将被FirstOrDefault返回的对象引用,除非它是一个Default,这种情况下你没有得到匹配。
示例:
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