2009-01-14 69 views
12

在.NET 3.5中,我想創建一個單接口:如何使用靜態成員創建.NET接口?

interface ISingleton <T> 
{ 
    public static T Instance {get;} 
} 

當然,這並不工作,但就是想什麼我中。有什麼建議麼?

編輯:我只是希望它是已知所有singeltons將有一個名爲實例的類類型的靜態屬性。它永遠在那裏。一個接口將是一個明確的表達方式。

回答

12

據我所知,一個接口不能成爲一個Singleton,因爲它實際上並不存在。接口是實施必須遵循的合同。因此,實現可以是單例,但Interface不能。

+1

我認爲OP意味着不同的東西。我瞭解以下問題:「單個類的接口描述如何在C#中看起來像?」 – 2009-01-14 22:22:46

+0

您不能從接口指定單例類,因爲接口只指定實施類可以以任何合適的方式滿足的合同。 – 2009-01-14 22:25:45

+2

AFAIK在C#中一個接口不能有靜態成員。但是,有些情況下靜態成員會有用。例如,您需要實現的CONTRACT,但所有這些實現都需要在該對象的實例之間共享的分類器。這並不是我第一次需要這樣的東西。 – 2012-06-01 04:37:26

1

除了它不起作用,正如你所說的,你將如何使用這個接口和一個實現類?

你可能有工廠風格的界面

interface ISingletonFactory<T> 
{ 
    public T Instance {get;} 
} 

public class SingletonFactory: ISingletonFactory<Singleton> 
{ 
    public Singleton Instance {get { return Singleton.Instance;}} 
} 

public class Singleton 
{ 
    private Singleton foo; 
    public static Singleton Instance { get { return foo; } } 
} 
0

指定接口的OOP的經典概念,將其定義爲實現類之間的合同試試,你不能添加這樣的事,作爲一個靜態方法到它。如果你能做到的話,你會以更類似於抽象類的方式結束,其中你將部分實現你的類和其他部分實現擴展類。

2

我只是想知道,所有的singeltons都會有一個名爲Instance類型的靜態屬性。它永遠在那裏。一個接口將是一個明確的表達方式。

寫一個單元測試代替。

0

正如指出的那樣,你不能這樣做,並且你不應該有這麼好的理由。

我已經在過去實現的方法創建一個接口和實現接口的抽象基類。它看起來像這樣:

public interface IMyCompanySetting 
{ 
    XmlNode Serialize(); 
    IMyCompanySetting Deserialize(XmlNode pattern); 
    string SettingName { get; } 

string Key {get; } object SettingValue {get;組; } SettingScope範圍{get;組; }}

public abstract class MyCompanySettingBase : IMyCompanySetting 
{ 
    public MyCompanySettingBase() {} 
    public MyCompanySettingBase(XmlNode pattern) 
    { 
     Deserialize(pattern); 
    } 
    #region IMyCompanySetting Members 

    public abstract XmlNode Serialize(); 
    public abstract IMyCompanySetting Deserialize(XmlNode pattern); 
    public abstract string SettingName{ get; } 
public abstract string Key { get; } 
    public abstract SettingScope Scope{ get; set; } 
    public abstract object SettingValue{ get; set; } 

    #endregion 

public static XmlNode WrapInSettingEnvelope(XmlNode innerNode, IMyCompanySetting theSetting) 
{ 
    // Write the top of the envelope. 
    XmlTextWriter xtw = null; 
    MemoryStream theStream = OpenSettingEnvelope(theSetting, ref xtw); 

    // Insert the message. 
    xtw.WriteNode(new XmlTextReader(innerNode.OuterXml, XmlNodeType.Element, null), true); 

    // Close the envelope. 
    XmlNode retNode = CloseSettingEnvelope(xtw, theStream); 
    return retNode; 

} 

public static MemoryStream OpenSettingEnvelope(IMyCompanySetting theSetting, ref XmlTextWriter theWriter) 
{ 
    MemoryStream theStream = new MemoryStream(); 
    theWriter = new XmlTextWriter(theStream, Encoding.ASCII); 
    System.Type messageType = theSetting.GetType(); 

    string[] fullAssembly = messageType.Assembly.ToString().Split(','); 
    string assemblyName = fullAssembly[0].Trim(); 

    theWriter.WriteStartElement(theSetting.SettingName); 
    theWriter.WriteAttributeString("type", messageType.ToString()); 
    theWriter.WriteAttributeString("assembly", assemblyName); 
    theWriter.WriteAttributeString("scope", ConfigurationManager.ScopeName(theSetting.Scope)); 

    return theStream; 
} 

public static XmlNode CloseSettingEnvelope(XmlTextWriter xtw, MemoryStream theStream) 
{ 
    XmlDocument retDoc = new XmlDocument(); 
    try 
    { 
     // Close the envelope. 
     xtw.WriteEndElement(); 
     xtw.Flush(); 

     // Return the node. 
     string xmlString = Encoding.ASCII.GetString(theStream.ToArray()); 
     retDoc.LoadXml(xmlString); 
    } 
    catch (XmlException) 
    { 
     string xmlString = Encoding.ASCII.GetString(theStream.ToArray()); 
     Trace.WriteLine(xmlString); 
     retDoc.LoadXml(@"<error/>"); 
    } 
    catch (Exception) 
    { 
     retDoc.LoadXml(@"<error/>"); 
    } 
    return retDoc.DocumentElement; 
} 

} 
4

好吧我做了這樣的回答一個Wiki,因爲我只是要提供一個意見,即是在切線你的問題。

我個人認爲Singletons被waaay過度使用,它的一個用例是IMO實際上很少見,在大多數情況下,靜態類可以更好地適應用例,而在其他情況下,只有工廠創建的不可變對象是最好的選擇,實際的單身人士比人們想象的要稀罕得多。

我就不會來形容一個常見的模式的接口,因爲我真的希望每一個使用一個單獨的加以考慮非常謹慎和合理的。

2

我知道這不是你的問題,但究竟有多少單身,你有這樣的,你需要一個接口?這對我來說聽起來很糟糕 - 你能否清楚地解釋爲什麼這些類應該是單例而不是實例?如果你的答案是記憶,我會建議你推翻你的應用程序,如果你真的擔心,看看flyweight模式(或者一個簡單的工廠模式)。對不起,沒有直接回答這個問題,但這聽起來不是一個好主意。

7

雖然我與其他海報是單身都非常超過使用達成一致,有可能自己解決你的問題是提供一個抽象基類派生單的類型參數:

public abstract class Singleton<T> where T : Singleton<T> 
{ 
    private static T _instance; 

    public static T Instance 
    { 
    get { return _instance; } 
    protected set { _instance = value; } 
    } 
} 

任何類從單身派生將有正確類型的靜態實例屬性:

public class MySingleton : Singleton<MySingleton> 
{ 
    static MySingleton() 
    { 
     Instance = new MySingleton(); 
    } 

    private MySingleton() { } 
} 

使用這樣的事情之前,雖然你真的應該考慮一下是否需要一個單獨或者如果你是一個普通的靜態類更好。