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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 14:57:35  来源:igfitidea点击:

singleton pattern in vb

vb.netsingleton

提问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.InstanceWhat 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.Instanceand 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.ExecutionAndPublicationto 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 propertyto 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 Instanceproperty orthe Createmethod, 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