我通常是ac #programmer,但我正在VB中为这个项目工作,当我用来设置单例类时我会遵循Jon Skeet模型
public sealed class Singleton
{
static Singleton instance = null;
static readonly object padlock = new object();
Singleton()
{
}
public static Singleton Instance
{
get
{
lock (padlock)
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
//Added to illustrate the point
public static void a()
{
}
public void b()
{
}
}
Run Code Online (Sandbox Code Playgroud)
如果我在c#中编写语句,或者其中一个变体
Singleton.Instance 什么程序是所有非静态的成员,b而不是a.
现在我在VB中做同样的事情
Private Shared _instance As StackTracker
Private Shared ReadOnly _lock As Object = New Object()
Private Sub New()
_WorkingStack = New Stack(Of MethodObject)
_HistoryStack = New Queue(Of MethodObject)
End Sub
Public Shared ReadOnly Property Instance() As StackTracker
Get
SyncLock _lock
If (_instance Is Nothing) Then
_instance = New StackTracker()
End If
End SyncLock
Return _instance
End Get
End Property
Run Code Online (Sandbox Code Playgroud)
我得到StackTracker.Instance.Instance它继续前进,而它不是世界末日它看起来很糟糕.
问题是VB中有一种方法可以隐藏第二个实例,这样用户就无法递归调用Instance吗?
run*_*run 14
这是完整的代码:
Public NotInheritable Class MySingleton
Private Shared ReadOnly _instance As New Lazy(Of MySingleton)(Function() New
MySingleton(), System.Threading.LazyThreadSafetyMode.ExecutionAndPublication)
Private Sub New()
End Sub
Public Shared ReadOnly Property Instance() As MySingleton
Get
Return _instance.Value
End Get
End Property
End Class
Run Code Online (Sandbox Code Playgroud)
然后使用此类,使用以下命令获取实例:
Dim theSingleton As MySingleton = MySingleton.Instance
Run Code Online (Sandbox Code Playgroud)
这实际上不是乔恩提出的建议.您实现了关于此事的文章中引用的第三个版本,由于缺乏内存障碍,他指出该版本不符合EMCA规范.
相反,您应该使用第五个版本,它使用嵌套类并在嵌套类的静态字段的声明中执行实例的赋值.
如果您使用的是.NET 4.0,那么您不必执行任何操作.您可以创建类型的静态只读字段Lazy<T>,传递LazyThreadSafetyMode.ExecutionAndPublication给构造函数(以及Func<T>指示如何创建实例)以保证仅创建一次值.
然后,您公开一个属性,它只是调用Lazy<T>.Value propertyto来返回延迟加载的单例值.
小智 5
最初的问题不是关于如何实现单例模式,而是指以下事实:在C#中,尝试通过实例访问静态成员是编译器错误。在当前的VB中,这是一个警告。
解决方案:您可以将项目编译器设置更改为“将所有警告视为错误”,但是我不知道有什么方法可以将警告42025视为错误。
话虽如此,在VB中实现单身人士的方法也简单得多:
public class Singleton
private sub new()
end sub
public shared readonly property Instance as Singleton
get
static INST as Singleton = new Singleton
return INST
end get
end property
end class
Run Code Online (Sandbox Code Playgroud)
这依赖于静态变量的VB线程安全的单个初始化,而C#中没有此功能。即使从多个线程访问了Instance属性很多,以单词“ static”开头的代码行也只会被评估一次。