簡體   English   中英

使用通用對象初始化非泛型對象

[英]Initialize a non-generic object with a generic object

有時候,我不明白那些T的C#泛型正確s。 我有一個通用的結構

public struct ValueWithUnit<T>
{
    public ValueWithUnit(T _value, Unit _unit)
    {
        Unit = _unit;
        Value = _value;
    }
    public Unit Unit { get; }
    public T Value { get; }
}

UnitenumT應該是數字,但沒有可用於此目的的約束)。

對於WCF,我需要一個非泛型版本, Tdouble 所以我想到了:

public struct DoubleValueWithUnit 
{
    public DoubleValueWithUnit(double _value, Unit _unit)
    {
        Unit = _unit;
        Value = _value;
    }
    public DoubleValueWithUnit(ValueWithUnit<T> _valueWithUnit)
    {
        Unit = _valueWithUnit.Unit;
        Value = Convert.ToDouble(_valueWithUnit.Value);
    }
    public Unit Unit { get; set; }
    public double Value { get; set; }
}

但是第二個構造函數沒有編譯: error CS0246: The type or namespace name 'T' could not be found ...而Convert.ToDouble抱怨Cannot resolve method 'ToDouble(T)' Candidates are...

我知道我可以在泛型類中添加轉換方法:

    public DoubleValueWithUnit ToDoubleValueWithUnit()
    {
        return new DoubleValueWithUnit(Convert.ToDouble(Value), Unit);
    }

這樣可行。 但是有沒有可能將帶有泛型參數的構造函數添加到非泛型類/結構中?

我不認為這個構造函數應該存在:

public DoubleValueWithUnit(ValueWithUnit<T> _valueWithUnit)
{
    Unit = _valueWithUnit.Unit;
    Value = Convert.ToDouble(_valueWithUnit.Value);
}

為什么要將ValueWithUnit<T>轉換為DoubleValueWithUnit 對於某些T值,這沒有意義。 你如何將BinaryFormatter轉換為double 還是要doubleForm 在編譯時不應該允許這些。

所以你要么這樣做:

public DoubleValueWithUnit(ValueWithUnit<double> _valueWithUnit)
{
    Unit = _valueWithUnit.Unit;
    Value = _valueWithUnit.Value;
}

或者一起刪除構造函數。

在第二個例子中,簡單地沒有定義T. 所以你不能在該結構的上下文中使用T.

只需刪除此構造函數:

public DoubleValueWithUnit(ValueWithUnit<T> _valueWithUnit)

由於您希望轉換傳遞給Double的任何內容,因此定義一個構造函數作為對象的輸入。 在構造函數中,如果對象不可轉換,請嘗試強制轉換並拋出異常。

public DoubleValueWithUnit(object obj, Unit unit)
{
    Unit = unit;
    try
    {
       Value = Convert.ToDouble( obj );
    }
    catch( Exception )
    {
       throw new ArgumentException("Cannot convert to double", nameof(obj) );
    }        
}

我目前的解決方案是讓結構實現一個通用接口,該接口繼承自非通用接口:

public struct ValueWithUnit<T> : IValueWithUnit<T> {...}

public interface IValueWithUnit<out T> : IValueWithUnit // where T: number
{
    new T Value { get; }
}
public interface IValueWithUnit
{
    object Value { get; }
    Unit Unit { get; }
}

現在,我可以將ValueWithUnit<T>傳遞給(已修改的)構造函數:

public DoubleValueWithUnit(IValueWithUnit _valueWithUnit)
{
    Unit = _valueWithUnit.Unit;
    Value = Convert.ToDouble(_valueWithUnit.Value);
}

我仍然不確定是否有更好的解決方案。

暫無
暫無

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

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