2011-09-13 128 views
7

我需要一種方法來創建一個靜態類,其中一些常量可以是特定的,但硬編碼。靜態抽象類

我真正想要做的是有一個類,其中提供了幾個常量時擴展類 - 我想'常量'硬編碼。我想我會做一些抽象的屬性,並定義get {return constant; }擴展類時。

我知道這是不可能的,所以現在我面臨兩個選擇,我想知道什麼是最好的,爲什麼(如果有我錯過選項,請讓我知道!)

  1. 創建帶有空字段的靜態類,如果在調用靜態方法時字段爲空,則拋出異常。
  2. 放棄靜態類。具有抽象屬性的非靜態類,並在需要的地方創建對象的實例,即使所有功能都是靜態的。

我知道這可能是主觀的和依賴於個案的,但是當我想到這個問題時我會繞着圈子走,並且真的可以用一些外部輸入。我希望可以不做我想做的事情,我只是想着這個錯誤。

更新:代碼:我將嘗試編寫一些描述我想完成的代碼。 我知道這段代碼無法工作!

想象一下,抽象類Calculation是在一個dll中,被許多項目使用。它們的功能都是一樣的,只是常量因項目而異。

public abstract static class Calculation 
{ 
    private abstract int Constant { get; } //The constant is unknown at this time 

    public static int Calculate(int inputValue) 
    { 
     return inputValue * Constant; 
    } 
} 

計算值是在一個單獨項目在需要的功能和常數是已知的定義的類。

public static class Calc : Calculation 
{ 
    private override int Constant { get { return 2; } 
} 

... 

static class Program 
{ 
    [STAThread] 
    static void Main() 
    { 
     //At some point: 
     int result = Calc.Calculate(6); 
    } 
} 

我想最簡單的方法是創建一個非靜態類,並創建一個實例,但是我怕具有類的幾個實例可能是昂貴的,並且想阻止,如果可能的。

我看不出如何將它寫成單例模式,而無需在每個項目中再次寫入 - 在dll中只有嵌套類。這並不妨礙實現者創建一個普通的類,並有可能重新開始使用代碼的每個項目的辯論。

更新#2:我與方案一彪是這樣的:

類在DLL:

public static class Calculation 
{ 
    public int? Constant {get; set;} 

    public static int Calculate(int inputValue) 
    { 
     if (Constant == null) 
      throw new ArgumentNullException(); 

     return inputValue * (int)Constant; 
    } 
} 

在一個單獨的項目中的功能的使用方法:

static class Program 
{ 
    [STAThread] 
    static void Main() 
    { 
     //At some point: 
     Calculation.Constant = 2; 
     int result = Calc.Calculate(6); 
    } 
} 

選項一是非常簡單和優雅,什麼都困擾我,沒有什麼實現者設置常量。我擔心一個(不可能的)情景,在這種情況下,一個不起眼的角落案件將導致財產不被設置,並且代碼失敗(並且最後一名嫌疑人不斷)...

+0

爲什麼你認爲你需要一個靜態類?而「特定案例,但硬編碼」是什麼意思?你能發表一個具體的例子嗎? – svick

+0

您無法擴展(繼承)靜態類,那麼您的場景究竟是什麼?一小段代碼值1000字。 –

+0

你可以用一些示例來描述 - 可能不是可編譯的代碼嗎? –

回答

6

您可以創建跟隨單例的非靜態類,確保只有一個對象實例存在。我想這可能是下一個最好的事情。

+1

我沒有看到單身人士在這種情況下如何提供幫助。問題是關於繼承(不是單點的強點)和靜態屬性。 –

+0

[Anne Lagang]的評論(http://stackoverflow.com/users/906815/anne-lagang):「如果你需要Singleton的幫助,請查看Jon Skeet的[Singleton](http://csharpindepth.com/Articles/ General/Singleton.aspx)文章。「 –

5

你不能在同一時間想要靜態和繼承!它只是做出敏感!

如果您需要重寫行爲,您需要繼承!

如果你想調用(靜力學的優勢之一)的簡單,你可以使用廠(或單身人士,如果只需要一個實例)

我的猜測是,你可能不得不重新考慮你的模型。你的這一組常量可能代表你可以在一個單獨的類中提取的東西,然後將這個類傳遞給你的靜態方法。這是否符合您的需求?

1

編輯

爲了您的代碼示例:

public abstract static class Calculation 
{ 
    public static int Constant { get; set; } 
    public static int Calculate(int i) { return i * Constant; } 
} 

// ... 

Calculation.Constant = 6; 
Calculation.Calculate(123); 

有點更普遍的:

public abstract static class Calculation 
{ 
    public struct Context 
    { 
     public int Constant, SignificantDigits; 
     public bool Radians; 
    } 
    public static int Calculate(int i, Context ctx) { return i * ctx.Constant; } 
} 

// ... 
Calculation.Calculate(123, new Calculate.Context { Constant = 6 }); 

第一個想法:

我能想到的最接近的是仿製藥:

public interface ISpecifics 
{ 
    void DoSomething(); 
    string SomeProp { get; } 
} 

public static class Static<S> 
    where S : ISpecifics, new() 
{ 

     public static string ExerciseSpecific() 
     { 
      var spec = new S(); 
      spec.DoSomething(); 
      return spec.SomeProp; 
     } 
} 

或者,如果你真的需要單一的靜態類型

public static class Static 
{ 
     public static string ExerciseSpecific<S>() 
      where S : ISpecifics, new() 
     { 
      var spec = new S(); 
      spec.DoSomething(); 
      return spec.SomeProp; 
     } 
} 

這是否幫助?

+0

要編輯:這是我在原始問題中通過選項1進行修改。該屬性是int嗎?常量{get; set;}和Calculate(int inputValue){if(Constant == null)throw new NullArgumentException();返回inputValue *(int)常量; } –

+0

@David:我想我還在編輯中。現在檢查我的答案。 (如果更合適,你可以使用'int?'無論我說'int') – sehe

+0

實際的類型不會是int ?.它可能是字節[],我試圖做的一點是它可以爲空,這將表明一個錯誤。上下文的更一般選項不適用於我。請閱讀我的問題的底線,以瞭解爲什麼我不想使用此選項。 –

0

我需要幾乎相同的東西,所以首先我做了一個具有所有功能的非靜態類。 然後,在其靜態構造函數中實例化一個這樣的非靜態類的靜態類。 然後任何靜態方法調用相應的實例方法。

事情是這樣的:

public class CalculationInstance 
{ 
    private int constant; 

    public int Calculate(int inputValue) 
    { 
     return inputValue * constant; 
    } 

    public void AnyOtherMethod() 
    { 
    .... 
    }  

    public CalculationInstance(int constant) 
    { 
    this.constant=constant;  
    } 
} 


public static class Calculation 
{ 
    const int CONSTANT=2; 
    private CalculationInstance calc; 

    static Calculation() 
    { 
     calc=new CalculationInstance(CONSTANT); 
    } 

    public static int Calculate(int inputValue) 
    { 
     return calc.Calculate(inputValue); 
    } 

    public static void AnyOtherMethod() 
    { 
     calc.AnyOtherMethod(); 
    }  

} 

static class Program 
{ 
    [STAThread] 
    static void Main() 
    { 
     //At some point: 
     int result = Calculation.Calculate(6); 
    } 
}