繁体   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