当定义了隐式转换时,为什么此显式转换不起作用?

我有一个定义了到 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`,它们都不包含任何此类运算符。

以上是当定义了隐式转换时,为什么此显式转换不起作用?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>