簡體   English   中英

創建沒有在類上指定類型參數的通用類型成員變量

[英]Creating a generic typed member variable without type parameters specified on the class

對於標題不清楚,我深表歉意,我真的不知道該怎么說。 我將用代碼演示。

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();
    }
}

除了計算器對象的類型參數不同之外,我有很多相同的方法。

問題是,因為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>();
    }
}

但是private static Calculator<TInstrument, TResult> _calculator如果不指定CalculationService類型信息,就無法創建該private static Calculator<TInstrument, TResult> _calculator成員,而我不能使用WCF進行此操作。

我能想到的唯一方法是

private static dynamic _calculator;

還有其他辦法嗎? 如果可能的話,我寧願避免使用動態的,我不確定性能的影響(如果有)。

我不認為您后來對“僅在我的CalculationService類上擁有一個 Calculator實例”的評論不滿意。 相反,在我看來,每個<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();
  }
}

您可以使用繼承“老化”類型,以防止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缺少對通用類型參數的支持之前,我已經完成了此操作。

如果只需要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];
...

我知道這可能看起來很復雜,因為用於創建計算器字典的通用字典的通用語法...但是可以用。

希望這可以幫助,

埃里克。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM