2015-06-10 63 views
3

我曾經使用過單身人士,我知道這是一些解決靜態接口問題的人的解決方案。在我的情況下,我無法真正使用單例,因爲我有一個外部類,而且我無法控制這個(庫)。基本上,我有很多從「TableRow」(庫中的類)繼承的類,我需要每個這些類來實現某個靜態方法(例如:GetStaticIdentifier)。最後,我需要將這些對象存儲在它們的基本類型之一中,並對此特定類型使用靜態方法。等效的靜態接口C#

我的問題,是否有另一種解決方案,比使用單身?有沒有我不知道在C#中的功能可以幫助我解決這個問題?

+3

「我需要每一個這些類來實現某種靜態方法」爲什麼?什麼是用例?這些班級不應該爲自己的實施細節負責嗎? –

+1

爲什麼你不能只調用一個靜態方法?或者你需要每種類型都有給定名稱的獨特靜態方法? –

+0

是@AlexeiLevenkov,我需要在每個類上有不同的實現,該方法返回基類型的對象,但它應該是靜態方法實現的類型。 –

回答

5

看來你想提供一些元信息以及TableRow的子類;可以檢索的元信息而不實例化特定的子類

雖然.NET缺乏靜態接口和靜態多態,但可以(在某種程度上,請參見下文)使用custom attributes來解決。換句話說,你可以定義存儲要與您的類型相關聯的信息的自定義屬性類:

[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] 
public class StaticIdentifierAttribute : Attribute 
{ 
    public StaticIdentifierAttribute(int id) 
    { 
     this.staticIdentifier = id; 
    } 

    private readonly int staticIdentifier; 

    public int StaticIdentifier { 
     get { 
      return staticIdentifier; 
     } 
    } 
} 

然後,您可以將此自定義屬性應用到您的TableRow子類:

[StaticIdentifier(42)] 
public class MyTableRow : TableRow 
{ 
    // ... 
} 

你可以檢索MyTableRow(或TableRow的任何其他子類)的Type實例,並使用GetCustomAttributes method檢索該類的StaticIdentifier屬性。

缺點與靜態接口和靜態多態性相比,它不是編譯時確保每個TableRow子類實際上都具有該屬性;您將不得不在運行時捕獲該錯誤(並且要麼拋出異常,要麼忽略相應的TableRow子類)。

而且,你不能保證該屬性是應用於TableRow子類,但後來,雖然這可能有點凌亂,它並不真正的問題(如果將它應用到另一個類,它只會在那裏沒有任何效果,因爲沒有代碼爲其他類進行處理)。

0

如果你扭結自己,你可以得到少量的編譯器檢查。然而,爲每個你想要的標識符實例聲明一個新的結構類型肯定是瘋了。

public interface IIdentifier 
{ 
    int Id { get; } 
} 

public class BaseClass { } 

public class ClassWithId<T> : BaseClass where T : IIdentifier, new() 
{ 
    public static int Id { get { return (new T()).Id; } } 
} 

public struct StaticId1 : IIdentifier 
{ 
    public int Id { get { return 1; } } 
} 

public struct StaticId2 : IIdentifier 
{ 
    public int Id { get { return 2; } } 
} 

//Testing 
Console.WriteLine(ClassWithId<StaticId1>.Id); //outputs 1 
Console.WriteLine(ClassWithId<StaticId2>.Id); //outputs 2 
0

如何使用靜態類與通用(或不)擴展方法?

public static class Helper 
{ 
    fields... 

    public static void DoSomething<T>(this T obj) 
    { 
    do something... 
    } 
}