This is more a question of terminology than how to do something.
I found a sort of 3rd state a property can be in. The first is a valid property. For example, bool is true or false. The second is null. The third I do not know what to call it. It is a property of an object that has been instantiated. This property kind of looks like it has not been instantiated. Not sure is that is the proper way to state it.
Example: Working with System.Diagnostics.Process to open a virtual keyboard, OSK. I need a routine to toggle the keyboard on and off. This works great.
using System.Diagnostics;
namespace Bsc
{
public static class OnScreenKeyboard
{
private static Process virtualKeyboard = new Process();
public static void ToggleHideShow()
{
try
{
if (virtualKeyboard.HasExited)
virtualKeyboard = Process.Start("osk.exe");
else
virtualKeyboard.Kill();
}
catch
{
virtualKeyboard = Process.Start("osk.exe");
}
}
}
}
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Looking at the object virtualKeyboard in a watch window I can see how virtualKeyboard has been instantiated, but not completely. On the first pass virtualKeyboard.HasExited throws an exception. Watching the watch window, it also looks like it is not there. The line has a nice bright red dot in front of it with an X in it.
Name | Value | Type |
---|---|---|
HasExited | 'virtualKeyboard.HasExited' threw an exception of type 'System.InvalidOperationException' | bool {System.InvalidOperationException} |
Still on first pass the try/catch jumps to the Process.Start. After this executes the line looks like you would expect for an instantiated property.
Name | Value | Type |
---|---|---|
HasExited | false | bool |
All calls after the first one HasExited works like you would expect and the method toggles the keyboard on and off.
I have not run into an object before that seemingly was only partially instantiated. What are the proper technical terms for this scenario? I have used the term ‘instantiated’, is that correct?
CodePudding user response:
As per the documentation, the HasExited
property throws an InvalidOperationException
when there is no OS process associated with the Process
instance.
Your property is initialized to a new instance of the Process
class, which has not been started. Therefore, there is no OS process associated with that instance, and the HasExited
property will throw an exception.
Remove the field initializer, and test for null
in your method.
public static class OnScreenKeyboard
{
private static Process virtualKeyboard;
public static void ToggleHideShow()
{
try
{
if (virtualKeyboard == null || virtualKeyboard.HasExited)
virtualKeyboard = Process.Start("osk.exe");
else
virtualKeyboard.Kill();
}
catch
{
virtualKeyboard = Process.Start("osk.exe");
}
}
}
CodePudding user response:
It is not possible for an object to be half-initialised based on the working of the language. If an object is not in a correct state, this is due to the working of the class/properties etc, and how the code has been written to initialise the object or not throw an exception when accessing the properties.
If the object does not always do what you expect then you have to check for the exception, do some defensive coding and handle the various scenarios in your own code.