这是c# 6中的有效单例吗

时间:2022-09-02 08:50:50

I was making this to implement a singleton pattern

我这样做是为了实现一个单例模式

private static ProcessDao _dao;
public static ProcessDao Dao
{
    get { return _dao ?? (_dao = new ProcessDao()); }
}

but in C# 6 auto properties has default values. Is this a correct implementation of singleton?

但是在c# 6中,自动属性有默认值。这是单例的正确实现吗?

public static ProcessDao Dao { get; } = new ProcessDao();

1 个解决方案

#1


1  

Is this a correct implementation of singleton?

这是单例的正确实现吗?

Your first example is wrong in the sense that it isn't a thread-safe implementation of a singleton. If multiple threads called ProcessDao.Instance, you're likely to see different instances of the private field being created.

第一个示例是错误的,因为它不是单例的线程安全实现。如果多个线程调用ProcessDao。实例,您可能会看到正在创建的私有字段的不同实例。

In contrary to that, your second example is thread-safe, as the compiler actually translates your auto-implemented getter only property to:

相反,第二个示例是线程安全的,因为编译器实际上将自动实现的getter的属性转换为:

public class ProcessDao
{
    [CompilerGenerated]
    private static readonly ProcessDao <Dao>k__BackingField;
    public static ProcessDao Dao
    {
        [CompilerGenerated]
        get
        {
            return ProcessDao.<Dao>k__BackingField;
        }
    }
    static ProcessDao()
    {
        ProcessDao.<Dao>k__BackingField = new ProcessDao();
    }
}

The static constructor invocation is guaranteed by the runtime to at most once, so you're also getting the guarantee that this will not create multiple instances of the backing field.

静态构造函数调用是由运行时最多保证的,因此您也得到了保证,它不会创建支持字段的多个实例。

Regarding laziness, that depends on the implementation of your ProcessDao class. The static constructor is guaranteed to run before the first reference of a static field in the class. If you have multiple static fields exposed, then the first will cause the invocation and the allocation of these objects. If you know you'll be using other static members and want maximum laziness, look into the Lazy<T> type introduced in .NET 4.0.

关于惰性,这取决于ProcessDao类的实现。静态构造函数保证在类中静态字段的第一个引用之前运行。如果您公开了多个静态字段,那么第一个字段将导致调用和这些对象的分配。如果您知道您将使用其他静态成员并想要最大的惰性,请查看. net 4.0中引入的惰性< t>类型。

#1


1  

Is this a correct implementation of singleton?

这是单例的正确实现吗?

Your first example is wrong in the sense that it isn't a thread-safe implementation of a singleton. If multiple threads called ProcessDao.Instance, you're likely to see different instances of the private field being created.

第一个示例是错误的,因为它不是单例的线程安全实现。如果多个线程调用ProcessDao。实例,您可能会看到正在创建的私有字段的不同实例。

In contrary to that, your second example is thread-safe, as the compiler actually translates your auto-implemented getter only property to:

相反,第二个示例是线程安全的,因为编译器实际上将自动实现的getter的属性转换为:

public class ProcessDao
{
    [CompilerGenerated]
    private static readonly ProcessDao <Dao>k__BackingField;
    public static ProcessDao Dao
    {
        [CompilerGenerated]
        get
        {
            return ProcessDao.<Dao>k__BackingField;
        }
    }
    static ProcessDao()
    {
        ProcessDao.<Dao>k__BackingField = new ProcessDao();
    }
}

The static constructor invocation is guaranteed by the runtime to at most once, so you're also getting the guarantee that this will not create multiple instances of the backing field.

静态构造函数调用是由运行时最多保证的,因此您也得到了保证,它不会创建支持字段的多个实例。

Regarding laziness, that depends on the implementation of your ProcessDao class. The static constructor is guaranteed to run before the first reference of a static field in the class. If you have multiple static fields exposed, then the first will cause the invocation and the allocation of these objects. If you know you'll be using other static members and want maximum laziness, look into the Lazy<T> type introduced in .NET 4.0.

关于惰性,这取决于ProcessDao类的实现。静态构造函数保证在类中静态字段的第一个引用之前运行。如果您公开了多个静态字段,那么第一个字段将导致调用和这些对象的分配。如果您知道您将使用其他静态成员并想要最大的惰性,请查看. net 4.0中引入的惰性< t>类型。