【发布时间】:2018-01-31 09:29:27
【问题描述】:
我有一个单例类,它在第一次调用属性时会懒惰地创建它的实例(属性副作用)。
namespace singletontest2
{
using System.Diagnostics;
using MySingleton = Singleton<MyClass>;
public class MyClass
{
private int val = 42;
public MyClass()
{
}
}
public static class Singleton<T> where T : new()
{
private static T t;
public static bool IsNull
{
get
{
return t == null;
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public static T Instance
{
get
{
if (t == null)
t = new T();
return t;
}
}
}
class Program
{
static void Main(string[] args)
{
var a = MySingleton.IsNull;
var d = MySingleton.Instance;
}
}
}
如果我在Instance 属性getter 和var d 行中放置一个断点,当我进入Instance getter 时,t 成员将已经被初始化。
如果我将断点从var d 移到下一行,当我调试到Instance getter 时,t 为空。
我的印象是 DebuggerBrowsable 属性会阻止这种情况,但似乎没有任何区别。
但是,如果我消除上面的using MySingleton = Singleton<MyClass>; 并调用Singleton<MyClass>.Instance; 而不是MySingleton.Instance;,那么当我输入Instance getter 时,成员t 为空,而不管DebuggerBrowsable 这是我想要的.
为什么using 指令允许调试器在代码实际执行之前评估该属性?
【问题讨论】:
-
"如果我在 Instance 属性 getter 和 var d 行放置一个断点,当我进入 Instance getter 时,t 成员将已经被初始化" - - 我无法使用您提供的代码重现您声称的行为。当我踏入
Instancegetter 时,t的值是null。由于您上面的示例有一个MainWindow类,即您未能提供的代码,因此除了您共享的内容之外,您的代码中似乎还有其他内容,导致您观察到的内容。请修正问题,使其包含一个可靠地重现问题的良好 minimal reproducible example。 -
(注:我用的是VS2017)
-
原始示例代码使用的是默认 WPF 项目,没有其他代码。我将示例更改为控制台应用程序而不是 WPF 项目,但我仍然看到与以前相同的行为。也许这是 VS 2015 中的一个错误?
-
您是否在 Watch 窗口中的
MySingleton.Instance上设置了手表? -
@lesscode 也是不正确的,因为开发工具是明确的主题。请注意,目前只有一票接近,所以我不会担心。
标签: c# visual-studio debugging properties side-effects