在属性的getter方法中与可以为空的bool的类型转换混淆 [英] Confusion with typecast of nullable bool in getter method of a property
问题描述
亲爱的专家
我有以下测试代码:
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
事件才能看到错误:
如何:处理数据绑定时出现的错误和异常 [ ^ ]
TheBindingSource
is the reason. It suppresses exceptions thrown when reading the properties. You have to subscribe to theBindingComplete
event to see the errors:
How to: Handle Errors and Exceptions that Occur with Databinding[^]
这篇关于在属性的getter方法中与可以为空的bool的类型转换混淆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!