简体   繁体   中英

Warning as Error: Possible unintended reference comparison when upgrading from .Net 3.5 to .Net 4.5

Currently I am in the process of migrating a WPF application from .Net Framework 3.5 to .Net Framework 4.5. Next to the upgrade of the .Net Framework, the application will now be compiled 64-bits instead of 32-bits. I get the following error when compiling the application:

Warning as Error: Possible unintended reference comparison; to get a value comparison, cast the left hand side to type 'System.Type'

My question is: why does this error occur now that I have upgraded to .Net 4.5 and never before on .Net 3.5? I have not made any changes to the build properties of the project, both have the setting Treat warnings as errors set to All . Below is the code that produces the error, I have added some comments about the changes that I have made, the uncommented part compiles under .Net 4.5.

private void FoldersListBoxMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
    // Get typed sender
    ListBox typedSender = sender as ListBox;
    if (typedSender != null)
    {
        // Check if an item was double clicked
        //The line below worked in .Net 3.5, but not in .Net 4.5
        //if ((typedSender.SelectedItem != null) && (typedSender.InputHitTest(e.GetPosition(typedSender)) != typedSender.GetType()))
        //And this is the line that I have changed (I added GetType()!).
        if ((typedSender.SelectedItem != null) && (typedSender.InputHitTest(e.GetPosition(typedSender)).GetType() != typedSender.GetType()))
        {
            // Yes, set the new path
            SelectedPath = typedSender.SelectedValue as string;
        }
    }
}

Edit: I have looked up when this code was added to the application, but was unable to go find it, because the Subversion repository only goes back 6 years.

Your previous code was broken, basically. You say it worked, but I can't see that the condition would ever be false. I suspect the compiler is just smarter now than it was before. The condition was:

typedSender.InputHitTest(e.GetPosition(typedSender)) != typedSender.GetType()

Now InputHitTest returns a value of type IInputElement . So the condition (ignoring the first part) can be rewritten as:

IInputElement element = typedSender.InputHitTest(e.GetPosition(typedSender));
Type type = typedSender.GetType();
if (element != type)
{
    ...
}

The only way in which the two references could be equal would be if they were both null , and typedSender.GetType() will never return null , so the condition is pointless.

You're now comparing whether the input element which is the result of the hit test is of the same type as typedSender , which at least makes sense - although it doesn't check that it is typedSender .

It's worth noting that the documentation for InputHitTest includes:

This method typically is not called from your application code. Calling this method is only appropriate if you intend to re-implement a substantial amount of the low level input features that are already present, such as recreating mouse device logic.

Are you sure you want to call it?

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