在属性的getter方法中与可以为空的bool的类型转换混淆 [英] Confusion with typecast of nullable bool in getter method of a property

查看:75
本文介绍了在属性的getter方法中与可以为空的bool的类型转换混淆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

亲爱的专家

我有以下测试代码:

Dear experts
I have the following test code:

public class Person : INotifyPropertyChanged
{
    private bool? valid;

    public bool Valid
    {
        get
        {
            // Test only, expecting an exception in the next statement.
            valid = null;

            // Exception of typecast only shown while debugging *1)
            return ((bool)valid);
        }
        // ....
    }

    // ....
}

* 1)类型转换

这里我期待一个异常并在调试器中显示异常。

但是运行应用程序_without_ debugger没有异常会显示,但是是一个...只是没有显示。顺便说一句,我没有任何隐藏异常的尝试/捕获。



这与...相反...

*1) typecast
Here I expect an exception and in debugger the exception will be shown.
But running the application _without_ debugger no exception will be shown, but there is one... only not shown. Btw, I do not have any try/catch which hides the exception.

This in contrast to ...

private void buttonNullableBoolTest_Click(object sender, EventArgs e)
{
    bool? nullableBool = null;
    bool testBool= (bool)nullableBool; 
}

...抛出并显示_without_调试器异常System.InvalidOperationException:Nullable对象必须有值。



问题是:为什么应用程序没有显示异常?

任何想法,这次我不明白/错误解释?

提前谢谢。





对不起,经过多次测试后,我发现我需要更多在我的问题中是准确的。



a。)如果我直接在我的代码中访问该属性,例如 if(person.Valid)... 然后也会在调试器外显示异常。所以这里的一切都像预期的那样。



b。)但是如果我将属性绑定到例如在 BindingSource 的帮助下,按钮的Enabled属性比应用程序不显示异常。在这种情况下,看起来.NET确实隐藏了异常:(



[Edit2]

仅限于信息:直接在代码中绑定 buttonBindingTest.DataBindings.Add(new Binding(Enabled,person,Valid)); 也适用于预期的行为(应用程序确实显示异常一次)....但是Binding将消失的副作用:confused:



我尝试了什么:



在上面的问题中描述。

... which throws and Shows also _without_ debugger the exception "System.InvalidOperationException: Nullable object must have a value."

The question is: Why the application does not show the exception?
Any idea, what I do not understand/misinterpret this time here?
Thank you in advance.


Sorry, now after some more tests I see that I need to be more precise in my question.

a.) In case I access the property directly in my code e.g. if (person.Valid)... then the exception is shown also out of debugger. So here everything is like expected.

b.) But in case I bind the property to e.g. a button's Enabled property by the help of BindingSource than the app does not show the exception. It looks like .NET does hide the exception in this case :(


Only for information: Binding directly in code with buttonBindingTest.DataBindings.Add(new Binding("Enabled", person, "Valid")); does also works with the expected behaviour (the app does show the exception one time).... but with the side effect that Binding will disappear :confused:

What I have tried:

Described in the question above.

推荐答案

试试这个



try this

bool? nullableBool = null;
       bool? testBool = (bool?)nullableBool; // validate the testBool before usage

       // or

       bool? nullableBool = null;
       bool testBool = nullableBool.HasValue ? nullableBool.Value : false;  // if null, it will be assigned as false 





Nullable 类型使用 HasValue属性 [ ^ ]


当我在为发布而构建的应用程序中尝试它时,我收到运行时错误:Nullable对象必须有一个值。

When I try it in my app built for release I do get a runtime error: "Nullable object must have a value."
Person p = new Person();
Console.WriteLine(p.Valid);



所以我怀疑你有一个尝试 - 抓住它正在拾取它的地方。

检查你的调试设置:

调试菜单......例外......

在对话框中,检查抛出和用户未处理的列,看看你能做些什么来获得与发布版本相同的结果。



[更新]



抱歉延迟...我在想! (这需要一些时间......)

我可以复制你的问题并在VS中获得异常,但不是在直播非常简单,不使用BindingSource,只需移动有效的getter访问另一个主题:


So I would suspect you have a try - catch somewhere which is picking up on it.
Check your settings for debug:
"Debug" menu..."Exceptions..."
In the dialog, check the "thrown" and "user-unhandled" columns and see if there is anything you can do to get the same results as the release version.

[Update]

Sorry for the delay...I was thinking! (And that takes me some time...)
I can duplicate your problem and get an exception in VS but not when "live" very simply, without using a BindingSource, just by moving the Valid getter access to a different thread:

    {
    BackgroundWorker work = new BackgroundWorker();
    work.DoWork += work_DoWork
    work.RunWorkerAsync();
    }

void work_DoWork(object sender, DoWorkEventArgs e)
    {
    Person p = new Person();
    Console.WriteLine(p.Valid);
    }





这意味着绑定事件正在另一个线程上执行,吞下出于某种原因出现异常。



所以...我怀疑发生了什么:DataBinding正在不同的线程上执行代码,当异常未处理时,系统关闭线程并且不会在调试器外通知你。

快速测试:



Which implies that the bound event is being executed on a different thread, which "swallows" the exception for some reason.

So... What I suspect is happening: the DataBinding is executing the code on a different thread, and when the exception is unhandled, the system shuts down the thread and doesn't notify you outside of the debugger.
A quick test:

    BackgroundWorker work = new BackgroundWorker();
    work.DoWork += work_DoWork;
    work.RunWorkerAsync();
    ...
void work_DoWork(object sender, DoWorkEventArgs e)
    {
    try
        {
        Person p = new Person();
        Console.WriteLine(p.Valid);
        }
    catch (Exception ex)
        {
        File.WriteAllText(@"D:\Temp\aaaaa.txt", DateTime.Now.ToString() + " " + ex.Message);
        }
    }

并且每次都会记录异常。



你是什么?做到了吗?好问题:我建议尝试一下,但确切地说你把它放在哪里,我不知道......

And the exception is logged each end every time.

What do you do about it? Good question: I'd suggest a try-catch but exactly where you put it, I don't know...


BindingSource 是原因。它抑制了读取属性时抛出的异常。您必须订阅 BindingComplete 事件才能看到错误:

如何:处理数据绑定时出现的错误和异常 [ ^ ]
The BindingSource is the reason. It suppresses exceptions thrown when reading the properties. You have to subscribe to the BindingComplete event to see the errors:
How to: Handle Errors and Exceptions that Occur with Databinding[^]


这篇关于在属性的getter方法中与可以为空的bool的类型转换混淆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆