简体   繁体   中英

Casting to System.Drawing.Color?

When I want to cast an object to System.Drawing.Color (using as ), I got the following error at compile time :

The as operator must be used with a reference type or nullable type ('System.Drawing.Color' is a non-nullable value type)

What can I do ?

My code is like :

MyClass.indoorColor = parsedObject as System.Drawing.Color;

The System.Drawing.Color is a Struct and can't be casted with the 'as' keyword from a reference type to a value type.

Try to use one of the 'From..' Methods from System.Drawing.Color by passing parameters:

http://msdn.microsoft.com/en-us/library/system.drawing.color_methods.aspx

Private Function GetColorTxt(txtColor As String, DefaultSiBlanco As Drawing.Color) As Drawing.Color
    Dim colConvert As System.Drawing.ColorConverter = New System.Drawing.ColorConverter()
    Dim C As Drawing.Color
    Select Case txtColor
        Case "RED"
            C = Drawing.Color.Red
        Case "BLUE"
            C = Drawing.Color.Blue
        Case "CYAN"
            C = Drawing.Color.Cyan
        Case "WHITE"
            C = Drawing.Color.WhiteSmoke
        Case "MAGENTA"
            C = Drawing.Color.Magenta
        Case "BLACK"
            C = Drawing.Color.Black
        Case Is <> ""
            C = CType(colConvert.ConvertFromString(txtColor), System.Drawing.Color)
        Case Else
            C = DefaultSiBlanco
    End Select
    Return C
End Function

You can only use as for casting with reference types. System.Drawing.Color is a struct, and you must cast it like this:

MyClass.indoorColor = (System.Drawing.Color)parsedObject;

Update:
Just to elaborate: the reason you cannot use as for value types (and structs are value types), is because as will result in null if the variable you're trying to cast isn't compatible with the cast you're performing. And since a value type cannot be null , this is not allowed.

One option, as suggested by vc 74, is to make indoorColor nullable ( Color? ), or you can check if parsedObject is of the correct type before attempting the cast.

As operator can be used only with reference type . For other objects you must use direct cast.

You can use:

System.Drawing.Color color = (System.Drawing.Color)parsedObject;
MyClass.indoorColor = color;

Why you are getting the Exception: The as operator is like a cast operation. However, if the conversion is not possible, as returns null instead of raising an exception. Consider the following expression:

expression as type

It is equivalent to the following expression except that expression is evaluated only one time:

expression is type ? (type)expression : (type)null

ie The as operator doesn't throw an exception when it fails to cast your parsedObject but instead should fill the variable with null. But, because System.Drawing.Color is a non-nullable (struct or value type) type, it can't be casted to a null value (which can only be done with reference types) and hence the exception.

There are two ways of explicitly casting an object either directly

MyClass.indoorColor = (System.Drawing.Color)parsedObject;

or the safe cast method via the as operator, which is what you are using in the question. The direct cast will throw an InvalidCastException if parsedObject is not of the correct type where the safe case will return null. However, null is not a valid value for a struct and hence the error message you are getting.

There are two ways round this, both involve using a nullable type.

A nullable type is a wrapper round a struct type that allows the value to be additionally null and is specified by either the long format System.Nullable<System.Drawing.Color> or the short format that is just a ? on the end of the type System.Drawing.Color?

So either change your type definition of indoorColor to be System.Drawing.Color? and then do

MyClass.indoorColor = parsedObject as System.Drawing.Color?;

Or alternatively pick a default value you wish to use in the event of a incompatible type (I'm going to use Transparent here) and use the following syntax;

MyClass.indoorColor = parsedObject as System.Drawing.Color? ?? 
                                              System.Drawing.Color.Transparent;

The ?? notation means use the value on the left unless it is null otherwise use the value on the right;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM