CmdPal: Null pattern matching based on is expression rather than overridable operators (#40972)

What the title says. 😄 

Rather than relying on the potentially overloaded `!=` or `==` operators
when checking for null, now we'll use the `is` expression (possibly
combined with the `not` operator) to ensure correct checking. Probably
overkill for many of these classes, but decided to err on the side of
consistency. Would matter more on classes that may be inherited or
extended.

Using `is` and `is not` will provide us a guarantee that no
user-overloaded equality operators (`==`/`!=`) is invoked when a
`expression is null` is evaluated.

In code form, changed all instances of:

```c#
something != null

something == null
```

to:

```c#
something is not null

something is null
```

The one exception was checking null on a `KeyChord`. `KeyChord` is a
struct which is never null so VS will raise an error when trying this
versus just providing a warning when using `keyChord != null`. In
reality, we shouldn't do this check because it can't ever be null. In
the case of a `KeyChord` it **would** be a `KeyChord` equivalent to:

```c#
KeyChord keyChord = new ()
{
    Modifiers = 0,
    Vkey = 0,
    ScanCode = 0
};
```
This commit is contained in:
Michael Jolley
2025-08-18 06:07:28 -05:00
committed by GitHub
parent efb48aa163
commit 6acb793184
138 changed files with 395 additions and 431 deletions

View File

@@ -10,7 +10,6 @@ using Microsoft.CmdPal.UI.Views;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Input;
using Windows.System;
namespace Microsoft.CmdPal.UI.Controls;
@@ -50,7 +49,7 @@ public sealed partial class CommandBar : UserControl,
return;
}
if (message.Element == null)
if (message.Element is null)
{
_ = DispatcherQueue.TryEnqueue(
() =>

View File

@@ -44,7 +44,7 @@ public sealed partial class ContentFormControl : UserControl
// 5% BODGY: if we set this multiple times over the lifetime of the app,
// then the second call will explode, because "CardOverrideStyles is already the child of another element".
// SO only set this once.
if (_renderer.OverrideStyles == null)
if (_renderer.OverrideStyles is null)
{
_renderer.OverrideStyles = CardOverrideStyles;
}
@@ -55,19 +55,19 @@ public sealed partial class ContentFormControl : UserControl
private void AttachViewModel(ContentFormViewModel? vm)
{
if (_viewModel != null)
if (_viewModel is not null)
{
_viewModel.PropertyChanged -= ViewModel_PropertyChanged;
}
_viewModel = vm;
if (_viewModel != null)
if (_viewModel is not null)
{
_viewModel.PropertyChanged += ViewModel_PropertyChanged;
var c = _viewModel.Card;
if (c != null)
if (c is not null)
{
DisplayCard(c);
}
@@ -76,7 +76,7 @@ public sealed partial class ContentFormControl : UserControl
private void ViewModel_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (ViewModel == null)
if (ViewModel is null)
{
return;
}
@@ -84,7 +84,7 @@ public sealed partial class ContentFormControl : UserControl
if (e.PropertyName == nameof(ViewModel.Card))
{
var c = ViewModel.Card;
if (c != null)
if (c is not null)
{
DisplayCard(c);
}
@@ -95,7 +95,7 @@ public sealed partial class ContentFormControl : UserControl
{
_renderedCard = _renderer.RenderAdaptiveCard(result.AdaptiveCard);
ContentGrid.Children.Clear();
if (_renderedCard.FrameworkElement != null)
if (_renderedCard.FrameworkElement is not null)
{
ContentGrid.Children.Add(_renderedCard.FrameworkElement);
@@ -148,7 +148,7 @@ public sealed partial class ContentFormControl : UserControl
// Recursively check children
var result = FindFirstFocusableElement(child);
if (result != null)
if (result is not null)
{
return result;
}

View File

@@ -31,7 +31,7 @@ public sealed partial class ContextMenu : UserControl,
WeakReferenceMessenger.Default.Register<UpdateCommandBarMessage>(this);
WeakReferenceMessenger.Default.Register<TryCommandKeybindingMessage>(this);
if (ViewModel != null)
if (ViewModel is not null)
{
ViewModel.PropertyChanged += ViewModel_PropertyChanged;
}

View File

@@ -91,7 +91,7 @@ public partial class IconBox : ContentControl
{
if (d is IconBox @this)
{
if (e.NewValue == null)
if (e.NewValue is null)
{
@this.Source = null;
}
@@ -104,7 +104,7 @@ public partial class IconBox : ContentControl
var requestedTheme = @this.ActualTheme;
var eventArgs = new SourceRequestedEventArgs(e.NewValue, requestedTheme);
if (@this.SourceRequested != null)
if (@this.SourceRequested is not null)
{
await @this.SourceRequested.InvokeAsync(@this, eventArgs);
@@ -142,7 +142,7 @@ public partial class IconBox : ContentControl
iconData = requestedTheme == ElementTheme.Light ? info.Light : info.Dark;
}
if (iconData != null &&
if (iconData is not null &&
@this.Source is FontIconSource)
{
if (!string.IsNullOrEmpty(iconData.Icon) && iconData.Icon.Length <= 2)

View File

@@ -2,7 +2,6 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.CmdPal.UI;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Markup;
@@ -80,12 +79,12 @@ public sealed partial class KeyVisual : Control
private void Update()
{
if (_keyVisual == null)
if (_keyVisual is null)
{
return;
}
if (_keyVisual.Content != null)
if (_keyVisual.Content is not null)
{
if (_keyVisual.Content.GetType() == typeof(string))
{

View File

@@ -51,13 +51,13 @@ public sealed partial class SearchBar : UserControl,
//// TODO: If the Debounce timer hasn't fired, we may want to store the current Filter in the OldValue/prior VM, but we don't want that to go actually do work...
var @this = (SearchBar)d;
if (@this != null
if (@this is not null
&& e.OldValue is PageViewModel old)
{
old.PropertyChanged -= @this.Page_PropertyChanged;
}
if (@this != null
if (@this is not null
&& e.NewValue is PageViewModel page)
{
// TODO: In some cases we probably want commands to clear a filter
@@ -85,7 +85,7 @@ public sealed partial class SearchBar : UserControl,
{
this.FilterBox.Text = string.Empty;
if (CurrentPageViewModel != null)
if (CurrentPageViewModel is not null)
{
CurrentPageViewModel.Filter = string.Empty;
}
@@ -143,7 +143,7 @@ public sealed partial class SearchBar : UserControl,
FilterBox.Text = string.Empty;
// hack TODO GH #245
if (CurrentPageViewModel != null)
if (CurrentPageViewModel is not null)
{
CurrentPageViewModel.Filter = FilterBox.Text;
}
@@ -154,7 +154,7 @@ public sealed partial class SearchBar : UserControl,
else if (e.Key == VirtualKey.Back)
{
// hack TODO GH #245
if (CurrentPageViewModel != null)
if (CurrentPageViewModel is not null)
{
CurrentPageViewModel.Filter = FilterBox.Text;
}
@@ -318,7 +318,7 @@ public sealed partial class SearchBar : UserControl,
}
// Actually plumb Filtering to the view model
if (CurrentPageViewModel != null)
if (CurrentPageViewModel is not null)
{
CurrentPageViewModel.Filter = FilterBox.Text;
}

View File

@@ -39,13 +39,13 @@ public sealed partial class ShortcutControl : UserControl, IDisposable, IRecipie
private static void OnAllowDisableChanged(DependencyObject d, DependencyPropertyChangedEventArgs? e)
{
var me = d as ShortcutControl;
if (me == null)
if (me is null)
{
return;
}
var description = me.c?.FindDescendant<TextBlock>();
if (description == null)
if (description is null)
{
return;
}
@@ -431,7 +431,7 @@ public sealed partial class ShortcutControl : UserControl, IDisposable, IRecipie
private void ShortcutDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
if (lastValidSettings != null && ComboIsValid(lastValidSettings))
if (lastValidSettings is not null && ComboIsValid(lastValidSettings))
{
HotkeySettings = lastValidSettings with { };
}
@@ -458,7 +458,7 @@ public sealed partial class ShortcutControl : UserControl, IDisposable, IRecipie
private static bool ComboIsValid(HotkeySettings? settings)
{
return settings != null && (settings.IsValid() || settings.IsEmpty());
return settings is not null && (settings.IsValid() || settings.IsEmpty());
}
public void Receive(WindowActivatedEventArgs message) => DoWindowActivated(message);
@@ -466,12 +466,12 @@ public sealed partial class ShortcutControl : UserControl, IDisposable, IRecipie
private void DoWindowActivated(WindowActivatedEventArgs args)
{
args.Handled = true;
if (args.WindowActivationState != WindowActivationState.Deactivated && (hook == null || hook.GetDisposedState() == true))
if (args.WindowActivationState != WindowActivationState.Deactivated && (hook is null || hook.GetDisposedState() == true))
{
// If the PT settings window gets focussed/activated again, we enable the keyboard hook to catch the keyboard input.
hook = new HotkeySettingsControlHook(Hotkey_KeyDown, Hotkey_KeyUp, Hotkey_IsActive, FilterAccessibleKeyboardEvents);
}
else if (args.WindowActivationState == WindowActivationState.Deactivated && hook != null && hook.GetDisposedState() == false)
else if (args.WindowActivationState == WindowActivationState.Deactivated && hook is not null && hook.GetDisposedState() == false)
{
// If the PT settings window lost focus/activation, we disable the keyboard hook to allow keyboard input on other windows.
hook.Dispose();
@@ -490,7 +490,7 @@ public sealed partial class ShortcutControl : UserControl, IDisposable, IRecipie
{
if (disposing)
{
if (hook != null)
if (hook is not null)
{
hook.Dispose();
}

View File

@@ -84,7 +84,7 @@ public partial class Tag : Control
return;
}
if (tag.ForegroundColor != null &&
if (tag.ForegroundColor is not null &&
OptionalColorBrushCacheProvider.Convert(tag.ForegroundColor.Value) is SolidColorBrush brush)
{
tag.Foreground = brush;
@@ -114,7 +114,7 @@ public partial class Tag : Control
return;
}
if (tag.BackgroundColor != null &&
if (tag.BackgroundColor is not null &&
OptionalColorBrushCacheProvider.Convert(tag.BackgroundColor.Value) is SolidColorBrush brush)
{
tag.Background = brush;