vb.net vb中的单例模式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3319108/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
singleton pattern in vb
提问by Mike
I am normally a c# programmer but am now working in VB for this one project when I use to set up a singleton class I would follow the Jon Skeet model
我通常是 ac# 程序员,但现在我在 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()
{
}
}
or one of the variations now if I write the statement in c#
或者如果我在 c# 中编写语句,现在是其中一种变体
Singleton.Instance
What procedures is all of the members that are not static, b but not a.
Singleton.Instance
什么程序是所有的成员都不是静态的,b而不是a。
Now when I do the same in VB
现在当我在 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
I get StackTracker.Instance.Instance
and it keeps going, while it is not the end of the world it looks bad.
我得到StackTracker.Instance.Instance
并且它继续前进,虽然这不是世界末日,但它看起来很糟糕。
Question is there a way in VB to hide the second instance so the user can not recursively call Instance?
问题在VB中有没有办法隐藏第二个实例,这样用户就不能递归调用实例?
回答by rundavidrun
Here's the full code:
这是完整的代码:
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
Then to use this class, get the instance using:
然后要使用此类,请使用以下方法获取实例:
Dim theSingleton As MySingleton = MySingleton.Instance
回答by JustinMichel
The original question was not about how to implement the singleton pattern, but referring to the fact that in C# it's a compiler error to try to access a static member via an instance. In the current VB it's a warning.
最初的问题不是关于如何实现单例模式,而是指在 C# 中尝试通过实例访问静态成员是编译器错误的事实。在当前的 VB 中,这是一个警告。
Solution: You can change the project compiler settings to "Treat all warnings as errors", but I don't know any way to explicitly treat just warning 42025 as an error.
解决方案:您可以将项目编译器设置更改为“将所有警告视为错误”,但我不知道有什么方法可以明确将警告 42025 视为错误。
That being said, there is also a much simpler way to implement singletons in VB:
话虽如此,在 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
This relies on VB thread-safe single initialization of static variables which is a feature not found in C#. The line of code beginning with the word "static" is only evaluated once even if the Instance property is accessed many times from many threads.
这依赖于静态变量的 VB 线程安全单初始化,这是 C# 中没有的特性。即使从多个线程多次访问 Instance 属性,以单词“static”开头的代码行也只计算一次。
回答by casperOne
This is actually not the proposal put forth by Jon. You implemented the third version referenced in the article on the matter, which he points out doesn't work according to the EMCA spec due to lack of memory barriers.
这其实不是乔恩提出的建议。您实现了关于此事的文章中引用的第三个版本,他指出由于缺乏内存屏障,该版本不符合 EMCA 规范。
Rather, you should work with the fifth version, which uses a nested class and performs the assignment of the instance in the declaration of the static field on the nested class.
相反,您应该使用第五个版本,它使用嵌套类并在嵌套类的静态字段的声明中执行实例的分配。
If you are working in .NET 4.0, then you don't have to do any of this. You can create a static readonly field of type Lazy<T>
, passing LazyThreadSafetyMode.ExecutionAndPublication
to the constructor (along with your Func<T>
to indicate how to create the instance) to guarantee that the value will only be created once.
如果您在 .NET 4.0 中工作,那么您不必执行任何这些操作。您可以创建一个静态 readonly 类型的字段Lazy<T>
,传递LazyThreadSafetyMode.ExecutionAndPublication
给构造函数(与您Func<T>
一起指示如何创建实例)以保证该值只会被创建一次。
Then, you expose a property which simply calls the Lazy<T>.Value property
to return the lazy-loaded singleton value.
然后,您公开一个属性,该属性仅调用Lazy<T>.Value property
以返回延迟加载的单例值。
回答by SteveCinq
Maybe I'm missing something but I just do some variation on this, depending on what else is going on in the class:
也许我遗漏了一些东西,但我只是对此做了一些变化,具体取决于课堂上发生的其他事情:
Class MySingleton
'The instance initializes once and persists (provided it's not intentionally destroyed)
Private Shared oInstance As MySingleton = New MySingleton
'A property initialized via the Create method
Public Shared Property SomeProperty() As Object = Nothing
'Constructor cannot be called directly so prevents external instantiation
Private Sub New()
'Nothing to do
End Sub
'The property returns the single instance
Public Shared ReadOnly Property Instance As MySingleton
Get
Return oInstance
End Get
End Property
'The method returns the single instance while also initializing SomeProperty
Public Shared Function Create(
ByVal SomeParam As Object) As MySingleton
_SomeProperty = SomeParam
Return oInstance
End Function
End Class
Obviously, you would usually only provide eitherthe Instance
property orthe Create
method, not both (though you could if you wanted to for some reason).
很显然,你通常会只提供无论是在Instance
性能还是在Create
方法,不能同时(虽然你可以,如果你想出于某种原因)。
In its simplest form it's:
最简单的形式是:
Class MySingleton
Private Shared oInstance As MySingleton = New MySingleton
Private Sub New()
End Sub
Public Shared ReadOnly Property Instance As MySingleton
Get
Return oInstance
End Get
End Property
End Class