【问题标题】:C# Implicit conversion + Unboxing + Conditional expressionC#隐式转换+拆箱+条件表达式
【发布时间】:2011-04-15 10:11:57
【问题描述】:

我有一个字符串到画笔转换器,我在 WPF 中使用它来根据文本内容为列表框项目着色。

但是,您可能已经知道,当内部有更多具有相同文本的字符串项时,列表框的行为会出现问题,并且您开始随意单击,您可以获得更多选定项(视觉上)。

为了解决这个问题,我创建了一个 OutputMessage 类,我将其隐式用作字符串,但由于隐式转换为它转换的每个字符串创建 OutputMessage 的新实例,现在列表框比较实例而不是字符串值并且行为正确。

但是我让日志管理器在里面放了纯字符串,因为它总是以当前时间作为前缀并且没有重复,所以问题不会发生。

但我发现转换器中的拆箱情况很奇怪:

 public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            String txt = value is OutputMessage ? (OutputMessage)value : (String)value;

这样做你会得到:

错误 1 ​​无法确定条件表达式的类型,因为 'OutputMessage' 和 'string' 隐式相互转换

我们正在分配一个字符串,并且在任何情况下都存在隐式转换,所以我尝试使用条件表达式来选择一个“路径”来正确解箱值。

这里的问题是我不能用

String txt = (String)value;

String txt = (OutputMessage)value;

因为列表框项目可以是两者中的任何一个,从对象中拆箱值将失败。

我最终用 if 语句和类型检查解决了这个问题,但这有点扼杀了隐式转换的用处。我希望条件表达式可以处理这个:(

【问题讨论】:

  • 顺便说一句,这与拆箱无关;这仅适用于值类型。

标签: c# wpf implicit-conversion


【解决方案1】:

您知道的问题是,您有两种可以隐式转换的类型。

String txt = value is OutputMessage ? (OutputMessage)value : (String)value;

要执行此语句,首先对赋值的 RHS 求值,最终得到一个表达式,该表达式可以解释为具有 OutputMessageString 类型。它不考虑语句的 LHS 中的内容,因此这对编译器来说是模棱两可的。请记住,条件的两个部分的静态类型必须相同。在这种情况下,您应该明确说明您想要什么类型,将条件的两个部分都设为 StringOutputMessage 类型。

String txt = value is OutputMessage ? (String)(OutputMessage)value : (String)value;

另一方面,我会以这种方式重写它,以便您测试OutputMessage 的类型(假设OutputMessage 是引用类型):

var temp = value as OutputMessage;
String txt = temp != null ? (String)temp : (String)value;

【讨论】:

  • 我给你们两个点了个赞,但自从 Dan 先回答后,我接受了他的回答。谢谢!
  • var temp = value as OutputMessage;如果里面有字符串,会失败,拆箱不起作用:/
  • @Marino:OutputMessage 是值类型吗?如果真是这样,那这绝对行不通。请注意,装箱仅适用于值类型,否则视为类型转换。
【解决方案2】:

你可以这样做:

String txt = value is OutputMessage ? (String)(OutputMessage)value : (String)value;

或者,您可以修改 OutputMessage 以便其中一种转换是显式的而不是隐式的(即允许将 String 隐式转换为 OutputMessage,但要求将 OutputMessages 显式转换为 String。

【讨论】:

  • 哇,我从没想过在条件的一侧进行 unbox+cast。这优雅地解决了这个问题。谢谢! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-07
  • 1970-01-01
  • 1970-01-01
  • 2019-04-19
  • 1970-01-01
  • 2015-07-06
  • 1970-01-01
相关资源
最近更新 更多