当定义了隐式转换时,为什么此显式转换不起作用?
我有一个定义了到 int 的隐式转换的类:
public class SpeakerId
{
private int value;
public SpeakerId(int value)
{
this.value = value;
}
//integer conversions
public static implicit operator SpeakerId(int value) => new SpeakerId(value);
public static implicit operator int(SpeakerId obj) => obj.value;
...
}
使用这些转换运算符,我认为这段代码可以工作:
var value = new SpeakerId(3);
var speakerId = (int)value;
但它没有;它会导致Specified cast is not valid错误。为什么会这样?
更新:我的原始代码示例确实有效。我得到错误的地方是当有一个中间转换到对象时,就像在值转换器中那样:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var speakerId = (int)value;
return ...
}
或者,更容易看到:
var value = new SpeakerId(3);
object intermediate = value;
var speakerId = (int)intermediate;
回答
因此,(int)反对 anobject是拆箱,而不是强制转换,并且不调用任何转换运算符1。您需要将您的对象转换回您的引用类型,然后才能尝试申请(int)充当实际的转换:
var speakerId = (int)(SpeakerId)value;
或者您需要确保int在转换为之前转换为,object以便它是装箱的int并且可以拆箱。
或者,如果您不知道将是什么类型,value但您“确定”它会定义一个适当的转换运算符,您可以通过以下方式强制在运行时查找转换dynamic:
var speakerId = (int)(dynamic)value;
1除了枚举及其基本类型的一些奇怪之处外,拆箱必须与最初装箱的类型完全一致。
- @JoshuaFrank - 因为运行时不负责插入转换。编译器是,在这一点上(忽略装箱/拆箱问题)唯一考虑的类型是 `int` 和 `object`,它们都不包含任何此类运算符。