C#隐式转换+拆箱+条件表达式

时间:2011-04-15 00:35:32

标签: c# wpf implicit-conversion

我有一个String to Brush转换器,我在WPF中使用它来根据文本内容为Listbox项目着色。

但是,正如您可能已经知道的那样,当列表框中包含相同文本的更多字符串项并且您随意开始单击时,列表框会出现错误行为,您可以(视觉上)获得更多选定项目。

为了解决这个问题,我创建了一个我隐式用作字符串的类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语句和类型检查解决了这个问题,但是这有点杀死了隐式转换的用处。我希望条件表达式可以解决这个问题:(

2 个答案:

答案 0 :(得分:2)

你知道的问题是你有两种可以互相隐式转换的类型。

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;

答案 1 :(得分:1)

你可以这样做:

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

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