【发布时间】:2016-07-05 19:15:11
【问题描述】:
我今天尝试在我们的应用程序中调试一个带有重复 ID 的问题,我注意到从即时窗口运行的代码没有按预期运行。这是我用来测试的示例程序:
class Program
{
static void Main(string[] args)
{
ClassA a = new ClassA();
ClassB b = new ClassB();
Console.WriteLine(string.Format("A: {0}", a.Id));
Console.WriteLine(string.Format("B: {0}", b.Id));
Console.ReadLine();
}
}
public class ClassA
{
private static int _id = MySingleton.Instance.GetId(typeof(ClassA));
public int Id { get { return _id; } }
}
public class ClassB
{
private static int _id = MySingleton.Instance.GetId(typeof(ClassB));
public int Id { get { return _id; } }
}
public class MySingleton
{
private int _id = 0;
private object lockObj = new object();
Dictionary<string, int> _cache = new Dictionary<string, int>();
private static readonly MySingleton _mySingleton = new MySingleton();
public int GetId(Type t)
{
if (_cache.ContainsKey(t.FullName))
{
return _cache[t.FullName];
}
else
{
lock (lockObj)
{
Add(t.FullName, _id++);
return _id;
}
}
}
public void Add(string key, int value)
{
if (!_cache.ContainsKey(key))
_cache.Add(key, value);
}
public static MySingleton Instance
{
get { return _mySingleton; }
}
}
如果我运行这段代码,输出是
答:1 乙:2但是,如果我在static int _id 上设置断点并在“立即”窗口中检查MySingleton.Instance.GetId(typeof(ClassA)) 的值,那么它第一次显示1 的值,放置持续0,所以输出为:
如果我将断点放在 ClassB 中并在“立即”窗口中运行 MySingleton.Instance.GetId(typeof(ClassA)),它会第一次向我显示 2 的值,但在任何后续调用中仍为 1:
因为我使用的是_id++ 而不是++_id,所以我真正期望的是输出应该是
为什么会这样?
【问题讨论】: