2011-09-01 82 views
2

我爲不清楚的標題道歉,我真的不知道該怎麼說。我將用代碼演示。創建一個沒有在類上指定類型參數的泛型類型成員變量

public class CalculationService 
{ 
    private static Calculator<StaticInstrument, StaticResult> _staticCalculator; 
    private static Calculator<DynamicInstrument, DynamicResult> _dynamicCalculator; 
    private static readonly object IsInitializedLock = new object(); 

    public byte[] ProcessStatic() 
    { 
     lock (IsInitializedLock) 
     { 
      _staticCalculator = new Calculator<StaticInstrument, StaticResult>(); 
     } 

     return _staticCalculator.Calculate(); 
    } 

    public byte[] ProcessDynamic() 
    { 
     lock (IsInitializedLock) 
     { 
      _dynamicCalculator = new Calculator<DynamicInstrument, DynamicResult>(); 
     } 

     return _dynamicCalculator.Calculate(); 
    } 
} 

我有很多方法是相同的,除了Calculator對象的類型參數不同的事實。

問題是,因爲CalculationService是WCF服務,所以不能有有任何類型的參數。由於這個原因,我不能簡單地創建一個靜態成員Calculator<TInstrument, TResult>,因爲我不能在CalculationService上輸入參數。

理想的解決辦法是這樣的:

public class CalculationService 
{ 
    private static Calculator<TInstrument, TResult> _calculator; 
    private static readonly object IsInitializedLock = new object(); 

    public byte[] Process<TInstrument, TResult>() 
    { 
     lock (IsInitializedLock) 
     { 
      _calculator = new Calculator<TInstrument, TResult>(); 
     } 

     return _calculator.Calculate(); 
    } 

    public byte[] ProcessStatic() 
    { 
     return Process<StaticInstrument, StaticResult>(); 
    } 

    public byte[] ProcessDynamic() 
    { 
     return Process<DynamicInstrument, DynamicResult>(); 
    } 
} 

但是,如果沒有指定的CalculationService類型的信息,這是我不能做的WCF我不能創建private static Calculator<TInstrument, TResult> _calculator成員。

我能想到的唯一辦法做到這一點是有

private static dynamic _calculator; 

有沒有其他辦法?如果可能的話,我寧願避免使用動態,我不確定會有什麼性能影響。

+0

你可以使用接口嗎? – skaz

+0

看看這個了 http:// stackoverflow。com/questions/509803/naming-generic-datacontracts-in-wcf – Sam

+0

爲什麼不只在客戶端使用object和unbox數據,可能會使用一個工作類型安全的通用包裝? – Kolja

回答

1

我不認爲我理解你後來對「在我的CalculationService類中計算器的實例只有一個實例」的評論。相反,在我看來,您需要每個< TInstrument一個實例,TResult >,就像您最初發布的代碼一樣。我認爲下面的代碼會做你想做的事(額外的好處是靜態初始化規則將會在適當的時候安全地構造計算器)。

public class CalculationService { 
    private static class Inner<TInstrument, TResult> { 
    public static readonly Calculator<TInstrument, TResult> _calculator; 

    static Inner() { 
     _calculator=new Calculator<TInstrument, TResult>(); 
    } 
    } 

public byte[] ProcessStatic() { 
    return Inner<StaticInstrument, StaticResult>._calculator.Calculate(); 
    } 

    public byte[] ProcessDynamic() { 
    return Inner<DynamicInstrument, DynamicResult>._calculator.Calculate(); 
    } 
} 
0

您可以使用繼承來「燒入」類型,以防止WCF抱怨。

public class StaticCalculator:Calculator<StaticInstrument, StaticResult> {} 
public class DynamicCalculator:Calculator<DynamicInstrument, DynamicResult> {} 

public class CalculationService 
{ 
    private static StaticCalculator _staticCalculator; 
    private static DynamicCalculator _dynamicCalculator; 
    ... 

我解決WCF缺乏對泛型類型參數支持這樣做過。

+0

不,問題是我只想在我的CalculationService類中有*一個Calculator實例。具體的泛型類型正常工作。 – robertkroll

0

,如果你只想要1個版本的服務,你不能有一個_calculator變量。 「簡單」的方法是使用某種查找結構的版本(如字典等)並查找適當的計算器。使用TInstrumentTResult的組合作爲計算器的關鍵。

然後,您可以使用typeof運算符來獲取您的密鑰。喜歡的東西:

_calculators = new Dictionary<Type,<Dictionary<Type,Calculator<TInstrument, TResult>>>(); 
... 
var key1 = typeof(TInstrument); 
var key2 = typeof(TResult); 
var calculator = _calculators[key1].[key2]; 
... 

我知道這可能是因爲用於創建計算器的字典的通用字典仿製藥的語法看起來很複雜......但它的作品。

希望這有助於

埃裏克。

相關問題