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

本文关键字:拆箱 表达式 条件 转换 | 更新日期: 2023-09-27 17:50:18

我有一个字符串到笔刷转换器,我在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#隐式转换+拆箱+条件表达式

你知道的问题是你有两个隐式地相互转换的类型。

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;

你可以这样做:

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

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