开发者

C# Implicit conversion + Unboxing + Conditional expression

I have a String to Brush converter that I use in WPF to color Listbox items based on text content.

However, as you may already know, the listbox behaves buggy when more string items with the same text are inside and you begin clicking casually you can get more selected items (visually).

To solve this problem I created a class OutputMessage that I implicitly use as a string, but since implicit conversion creates new instances of OutputMessage for each string it converts now the listbox compares instances and not string values and behaves correctly.

But I left the logging manager put plain strings in there since it always prefixes with the current time and there are no duplicates, so the problem would not occur.

But I found a wierd situation with unboxing in the converter:

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

By doing this you get:

Error 1 Type of conditional expression cannot be determined because 'OutputMessage' and 'string' implicitly convert to one another

We are asigning to a String and there is an implicit conversion in any of the cases, so I tried to use the conditional expression to choose a 'path' for unboxing the value correctly.

The problem here is that I cannot use

String txt = (String)value;

or

String txt = (OutputMessage)value;

because the listbox item could be any of the two, and unboxing the value from object will fail.

I ultimately solved the problem with if statements and type checking, but that kinda kills the usefulness 开发者_如何学编程of implicit conversion. I hoped that conditional expressions coudl deal with this :(


The problem as you know is that you have two types that are implicitly convertible to each other.

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

To execute this statement, the RHS of the assignment gets evaluated first and you end up with an expression that could be interpreted as having a type OutputMessage or String. It does not account for what is in the LHS of the statement so this is ambiguous to the compiler. Remember, the static type of both parts of the conditional must be the same. You should be explicit about what type you want in this case making both parts of the conditional of type String or OutputMessage.

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

On the other hand, I would rewrite it this way so you're testing the type of the OutputMessage (assuming OutputMessage is a reference type):

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


You can do:

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

Alternately, you can modify OutputMessage so that one of the conversions is explicit rather than implicit (i.e. allow String to be implicitly converted to OutputMessage, but require OutputMessages to be explicitly converted to String.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜