簡體   English   中英

C#Singleton“GetInstance”方法或“實例”屬性?

[英]C# Singleton “GetInstance” Method or “Instance” Property?

從誰需要“得到 一個 實例”一個Singleton類的,你喜歡“獲得” 一個 在.Instance財產或API最終用戶的角度看“稱之為” .GetInstance()方法?

public class Bar
{
    private Bar() { }

    // Do you prefer a Property?
    public static Bar Instance
    {
        get
        {
            return new Bar();
        }
    }

    // or, a Method?
    public static Bar GetInstance()
    {
        return new Bar();
    }
}

在C#中,我更喜歡.Instance ,因為它符合一般准則。

如果要創建單例,則不能只在每個GetInstance調用或Instance屬性getter上返回新對象。 你應該做這樣的事情:

public sealed class Bar
{
    private Bar() { }

    // this will be initialized only once
    private static Bar instance = new Bar();

    // Do you prefer a Property?
    public static Bar Instance
    {
        get
        {
            return instance;
        }
    }

    // or, a Method?
    public static Bar GetInstance()
    {
        return instance;
    }
}

你選擇哪種方式並不重要。 如果您更喜歡使用屬性選擇它,如果您更喜歡方法,它也可以。

就像幾乎所有事情一樣,它取決於:)

如果單例是延遲加載的並且表示實例化的工作量不僅僅是一小部分,那么GetInstance()更合適,因為方法調用表明正在完成工作。

如果我們只是掩蓋以保護單例實例,則屬性更可取。

要看。 你需要傳遞參數嗎? 如果是這樣,我會做GetInstance()。 如果沒有,可能無關緊要(至少從主叫的角度來看,因為它們無論如何都是真正的方法;但是,如果你想要更加基於標准,那么它確實很重要,在這種情況下,會出現一個實例更好)。

public class Singleton
{

    private volatile static Singleton uniqueInstance;
    private static readonly object padlock = new object();

    private Singleton() { }

    public static Singleton getInstance()
    {
        if (uniqueInstance == null)
        {
            lock (padlock)
            {
                if (uniqueInstance == null)
                {
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance;
    }
}

在上面的代碼中,實現了雙重檢查,首先檢查是否創建了一個實例,是否已經建立了鎖定。一旦在這個塊中

                if (uniqueInstance == null)
                {
                    uniqueInstance = new Singleton();
                }

如果實例為null,則創建它。

此外,uniqueInstance變量聲明為volatile,以確保在訪問實例變量之前完成對實例變量的賦值。

我更喜歡財產,這些是標准模式。

正如@Rex所說,它取決於你想傳達的語義。

GetInstance()不一定意味着單例實例。 因此,在實例創建按需發生的情況下,我會使用GetInstance(),不希望直接new,並且實例可能是,但不保證是相同的。 對象池也符合這些標准。 (實際上,單例是具有狀態保存的對象池的特化:-))

另一方面,靜態實例屬性意味着單例和保留的實例標識。

順便說一句,正如@RaYell所提到的,您的示例代碼不是單例,因此您不應該使用Instance屬性。 在這種情況下,您仍然可以使用GetInstance()方法,因為它將用作實例工廠。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM