[英]Reference Not Null After Constructor Exception
I have the following line of code. 我有以下代码行。
Application.Current.MainWindow = new MainWindow();
Placing the constructor on the line the debugger tells me Application.Current.MainWindow is null. 将构造函数放在调试器的行上,告诉我Application.Current.MainWindow为null。 The constructor then throws an exception.
然后,构造函数将引发异常。 In the catch block Application.Current.MainWindow is no longer null.
在catch块中,Application.Current.MainWindow不再为null。 The value of Application.Current.MainWindow should not be modified, but it is.
Application.Current.MainWindow的值不应修改,但可以修改。
If I instead do: 如果我改为:
Window w = new MainWindow();
w is null after the exception is thrown as expected. 在按预期引发异常之后,w为null。
What am I missing? 我想念什么?
Update 更新
Just calling the constructor for a class that subclasses Window causes Application.Current.MainWindow to change to point to that instance. 只是调用子类Window的类的构造函数,就会导致Application.Current.MainWindow更改为指向该实例。 This occurs even if the constructor throws an exception.
即使构造函数抛出异常,也会发生这种情况。 This leaves the application in an inconsistent state.
这会使应用程序处于不一致状态。
For example, it will then let me call Application.Current.MainWindow.Show, which creates all sorts of issues, because the state of that Window is invalid. 例如,然后它将让我调用Application.Current.MainWindow.Show,它将创建各种问题,因为该Window的状态无效。
Check out the source of the Application.MainWindow
property 签出
Application.MainWindow
属性的源代码
Source: http://referencesource.microsoft.com/#PresentationFramework/Framework/System/Windows/Application.cs,cf9c51e402f97b05 来源: http : //referencesource.microsoft.com/#PresentationFramework/Framework/System/Windows/Application.cs,cf9c51e402f97b05
public Window MainWindow
{
get
{
VerifyAccess();
return _mainWindow;
}
set
{
VerifyAccess();
//
// Throw if an attempt is made to change RBW.
// or we are browser hosted, main window is null, and attempt is made to change RBW.
//
if ( ( _mainWindow is RootBrowserWindow )
||
((BrowserCallbackServices != null ) &&
( _mainWindow == null ) &&
( !( value is RootBrowserWindow ))) )
{
throw new InvalidOperationException( SR.Get( SRID.CannotChangeMainWindowInBrowser ) ) ;
}
if (value != _mainWindow)
{
_mainWindow = value;
}
}
}
This is one point of concern. 这是一个值得关注的问题。 The other point is that other thread or the framework itself can set it in some other place.
另一点是其他线程或框架本身可以将其设置在其他位置。 Check this comment
检查此评论
By default - MainWindow will be set to the first window opened in the application.
默认情况下-MainWindow将设置为在应用程序中打开的第一个窗口。 However the MainWindow may be set programmatically to indicate "this is my main window".
但是,可以通过编程方式设置MainWindow以指示“这是我的主窗口”。 It is a recommended programming style to refer to MainWindow in code instead of Windows[0].
建议使用一种编程风格,而不是Windows [0],而是用代码引用MainWindow。
There is no way that runtime can set a reference to a allocated memory before constructor finished. 在构造函数完成之前,运行时无法设置对已分配内存的引用。 It maybe done as an optimization, but only with a classes that are specific to framework, like
System.String
. 可能是作为优化来完成的,但只能使用特定于框架的类,例如
System.String
。
Edit: Look at Window.Initialize
method 编辑:看
Window.Initialize
方法
private void Initialize()
{
// AVTempUIPermission avtUIPermission = new AVTempUIPermission(AVTUIPermissionNewWindow.LaunchNewWindows);
// CASRemoval:avtUIPermission.Demand();
// this makes MeasureCore / ArrangeCore to defer to direct MeasureOverride and ArrangeOverride calls
// without reading Width / Height properties and modifying input constraint size parameter...
BypassLayoutPolicies = true;
// check if within an app && on the same thread
if (IsInsideApp == true)
{
if (Application.Current.Dispatcher.Thread == Dispatcher.CurrentDispatcher.Thread)
{
// add to window collection
// use internal version since we want to update the underlying collection
App.WindowsInternal.Add(this);
if (App.MainWindow == null)
{
App.MainWindow = this;
}
}
else
{
App.NonAppWindowsInternal.Add(this);
}
}
}
Specifically at lines: 特别是在行:
App.WindowsInternal.Add(this);
if (App.MainWindow == null)
{
App.MainWindow = this;
}
This is where Window
property gets set. 这是设置
Window
属性的地方。 And because your MainWindow
is derived from Window
, this happens before you get to throwing your exception. 而且由于
MainWindow
派生自Window
,所以在抛出异常之前就发生了这种情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.