[英]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; }
}
( Unit
是enum
, T
應該是數字,但沒有可用於此目的的約束)。
對於WCF,我需要一個非泛型版本, T
為double
。 所以我想到了:
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
? 還是要double
的Form
? 在編譯時不應該允許這些。
所以你要么這樣做:
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.