2017-02-10 82 views
1

我有一個類,它有一個靜態函數,其中返回該類的一個實例。類中的靜態函數返回類的一個實例

我只是想知道如果這是不好的做法使用。

public class Foo() 
{ 
    public int FooInt {get; private set;} 
    public string FooString {get; private set;} 

    public static Foo GetFoo() 
    { 
     Foo foo = new Foo(); 
     foo.FooInt = 5; 
     foo.FooString = "Test"; 

     return foo; 
    } 
} 
+4

nah。事實上,多數民衆議會是如何創建的 - 私人構造函數從靜態方法調用類 –

+0

這是很好,如果你想控制如何初始化類。但爲此,建議將任何構造函數設置爲「私有」,以便消費者無法解決這個問題。 –

+2

雖然也很好的提到單身人士經常因爲[反模式]而感到討厭(https://en.wikipedia.org/wiki/Anti-pattern)。示例:[什麼是單身人士這麼糟糕](http://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons) –

回答

6

這是一個工廠方法,所以你應該把它CreateFoo()NewFoo()代替GetFoo(),因爲你所選擇的名字所暗示的,一個FOO已經存在,你只是回到它。

工廠方法相當於構造函數。在某些情況下,如果繼承層次結構中有複雜的構造函數,並且每個構造函數都必須調用基構造函數,並且事情會變得非常複雜,因爲構造函數可能只在最初調用超構造函數時才執行任何其他語句計算要傳遞給基礎構造函數的東西。在這些情況下,預先計算工廠方法中需要計算的任何需求有時很有用。

-1

要控制實例創建,可以使用這種方法。將構造函數設置爲私有,並定義一個函數以「創建實例」。在這個函數中,您將檢查參數是否足以創建實例,如果不是,則返回null,否則返回對象。

-1

編輯:你描述的方法可能是非常有用的(正如其他答案中所述),但是這裏的具體例子並不僅僅是構造函數。

這似乎毫無意義,因爲它與構造函數完成相同的事情。

如果你想爲這個類的不同配置設置多個這些參數,爲什麼不把FoooInt和FooString當作構造函數參數呢?

+0

,那麼構造函數不會阻止某人創建多個實例會更好。 [Singleton](http://csharpindepth.com/Articles/General/Singleton.aspx) –

+0

我會理解,如果該方法返回一個變量重新初始化在類中聲明,而不是方法。這種方法如何防止某人爲兩個實例調用兩次GetFoo? – igoldthwaite

+0

那麼,你可以改變實現來返回一個已經創建的實例。如果你有一個正在使用的公共構造函數,那麼更改實現太遲了 –

0

如果你在做什麼真正試圖做的是實施辛格爾頓,您將得到更好的服務,審查各種實施方案喬恩斯基特廣泛article

TL; DR答案:

public sealed class Singleton 
{ 
private static readonly Singleton instance = new Singleton(); 

// Explicit static constructor to tell C# compiler 
// not to mark type as beforefieldinit 
static Singleton() 
{ 
} 

private Singleton() 
{ 
} 

public static Singleton Instance 
{ 
    get 
    { 
     return instance; 
    } 
} 
} 
+1

問題*不是*問如何創建一個單身。 – Servy

2

的唯一原因,要做到這一點,如果你不能指定在構造函數中所需的參數。例如,如果你想通過半徑或直徑來定義一個圓,並且構造函數不能區分這個差異。

// This class is immutable 
public class Circle 
{ 
    private Circle(double radius) { this.Radius = radius; } 
    public static Circle FromRadius(double radius) 
    { 
     return new Circle(radius); 
    } 
    public static Circle FromDiameter(double diameter) 
    { 
     return new Circle(diameter/2); 
    } 
    public double Radius {get; private set; } 
} 
+0

'System.TimeSpan'這樣做。 –

相關問題