diff --git a/.editorconfig b/.editorconfig index 8c7a4cefa3..004cba8b9c 100644 --- a/.editorconfig +++ b/.editorconfig @@ -162,6 +162,9 @@ dotnet_diagnostic.IDE0029.severity = warning # Use coalesce expression (nullable types). dotnet_diagnostic.IDE0030.severity = warning +# Use null propagation. +dotnet_diagnostic.IDE0031.severity = warning + # Use explicitly provided tuple name. dotnet_diagnostic.IDE0033.severity = warning diff --git a/OpenRA.Game/Graphics/ChromeProvider.cs b/OpenRA.Game/Graphics/ChromeProvider.cs index 79c9a1e596..8bb8a4a7e9 100644 --- a/OpenRA.Game/Graphics/ChromeProvider.cs +++ b/OpenRA.Game/Graphics/ChromeProvider.cs @@ -100,9 +100,7 @@ namespace OpenRA.Graphics static void LoadCollection(string name, MiniYaml yaml) { - if (Game.ModData.LoadScreen != null) - Game.ModData.LoadScreen.Display(); - + Game.ModData.LoadScreen?.Display(); collections.Add(name, FieldLoader.Load(yaml)); } diff --git a/OpenRA.Game/Graphics/CursorManager.cs b/OpenRA.Game/Graphics/CursorManager.cs index 85774d5625..1976679204 100644 --- a/OpenRA.Game/Graphics/CursorManager.cs +++ b/OpenRA.Game/Graphics/CursorManager.cs @@ -111,8 +111,7 @@ namespace OpenRA.Graphics var template = kv.Value; for (var i = 0; i < template.Sprites.Length; i++) { - if (template.Cursors[i] != null) - template.Cursors[i].Dispose(); + template.Cursors[i]?.Dispose(); // Calculate the padding to position the frame within sequenceBounds var paddingTL = -(template.Bounds.Location - template.Sprites[i].Offset.XY.ToInt2()); diff --git a/OpenRA.Game/Map/ActorInitializer.cs b/OpenRA.Game/Map/ActorInitializer.cs index a68eb90170..cf6d7dc403 100644 --- a/OpenRA.Game/Map/ActorInitializer.cs +++ b/OpenRA.Game/Map/ActorInitializer.cs @@ -54,7 +54,7 @@ namespace OpenRA // Traits tagged with an instance name prefer inits with the same name. // If a more specific init is not available, fall back to an unnamed init. // If duplicate inits are defined, take the last to match standard yaml override expectations - if (info != null && !string.IsNullOrEmpty(info.InstanceName)) + if (!string.IsNullOrEmpty(info?.InstanceName)) return inits.LastOrDefault(i => i.InstanceName == info.InstanceName) ?? inits.LastOrDefault(i => string.IsNullOrEmpty(i.InstanceName)); @@ -159,9 +159,9 @@ namespace OpenRA public virtual void Initialize(T value) { - var field = typeof(ValueActorInit).GetField(nameof(value), BindingFlags.NonPublic | BindingFlags.Instance); - if (field != null) - field.SetValue(this, value); + typeof(ValueActorInit) + .GetField(nameof(value), BindingFlags.NonPublic | BindingFlags.Instance) + ?.SetValue(this, value); } public override MiniYaml Save() @@ -246,16 +246,16 @@ namespace OpenRA public void Initialize(MiniYaml yaml) { - var field = typeof(OwnerInit).GetField(nameof(InternalName), BindingFlags.Public | BindingFlags.Instance); - if (field != null) - field.SetValue(this, yaml.Value); + typeof(OwnerInit) + .GetField(nameof(InternalName), BindingFlags.Public | BindingFlags.Instance) + ?.SetValue(this, yaml.Value); } public void Initialize(Player player) { - var field = typeof(OwnerInit).GetField(nameof(value), BindingFlags.NonPublic | BindingFlags.Instance); - if (field != null) - field.SetValue(this, player); + typeof(OwnerInit) + .GetField(nameof(value), BindingFlags.NonPublic | BindingFlags.Instance) + ?.SetValue(this, player); } public override MiniYaml Save() diff --git a/OpenRA.Mods.Common/Activities/Air/FallToEarth.cs b/OpenRA.Mods.Common/Activities/Air/FallToEarth.cs index ceef49f654..8e59779d4d 100644 --- a/OpenRA.Mods.Common/Activities/Air/FallToEarth.cs +++ b/OpenRA.Mods.Common/Activities/Air/FallToEarth.cs @@ -37,11 +37,8 @@ namespace OpenRA.Mods.Common.Activities { if (self.World.Map.DistanceAboveTerrain(self.CenterPosition).Length <= 0) { - if (info.ExplosionWeapon != null) - { - // Use .FromPos since this actor is killed. Cannot use Target.FromActor - info.ExplosionWeapon.Impact(Target.FromPos(self.CenterPosition), self); - } + // Use .FromPos since this actor is killed. Cannot use Target.FromActor + info.ExplosionWeapon?.Impact(Target.FromPos(self.CenterPosition), self); self.Kill(self); Cancel(self); diff --git a/OpenRA.Mods.Common/Activities/RepairBridge.cs b/OpenRA.Mods.Common/Activities/RepairBridge.cs index d75b398c56..6588da8e76 100644 --- a/OpenRA.Mods.Common/Activities/RepairBridge.cs +++ b/OpenRA.Mods.Common/Activities/RepairBridge.cs @@ -74,8 +74,8 @@ namespace OpenRA.Mods.Common.Activities if (enterLegacyHut != null) enterLegacyHut.Repair(self); - else if (enterHut != null) - enterHut.Repair(self); + else + enterHut?.Repair(self); Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", speechNotification, self.Owner.Faction.InternalName); TextNotificationsManager.AddTransientLine(textNotification, self.Owner); diff --git a/OpenRA.Mods.Common/ActorInitializer.cs b/OpenRA.Mods.Common/ActorInitializer.cs index 53cf1a2e1d..fea5c90f30 100644 --- a/OpenRA.Mods.Common/ActorInitializer.cs +++ b/OpenRA.Mods.Common/ActorInitializer.cs @@ -53,9 +53,9 @@ namespace OpenRA.Mods.Common public void Initialize(int value) { - var field = GetType().GetField(nameof(value), BindingFlags.NonPublic | BindingFlags.Instance); - if (field != null) - field.SetValue(this, value); + GetType() + .GetField(nameof(value), BindingFlags.NonPublic | BindingFlags.Instance) + ?.SetValue(this, value); } public override MiniYaml Save() diff --git a/OpenRA.Mods.Common/Traits/Player/PlaceBeacon.cs b/OpenRA.Mods.Common/Traits/Player/PlaceBeacon.cs index 538808b3fa..6ccac014e9 100644 --- a/OpenRA.Mods.Common/Traits/Player/PlaceBeacon.cs +++ b/OpenRA.Mods.Common/Traits/Player/PlaceBeacon.cs @@ -74,8 +74,7 @@ namespace OpenRA.Mods.Common.Traits self.World.Add(playerBeacon); if (self.Owner.IsAlliedWith(self.World.RenderPlayer)) - Game.Sound.PlayNotification(self.World.Map.Rules, null, info.NotificationType, info.Notification, - self.World.RenderPlayer != null ? self.World.RenderPlayer.Faction.InternalName : null); + Game.Sound.PlayNotification(self.World.Map.Rules, null, info.NotificationType, info.Notification, self.World.RenderPlayer?.Faction.InternalName); if (radarPings != null) { diff --git a/OpenRA.Mods.Common/Traits/World/StartGameNotification.cs b/OpenRA.Mods.Common/Traits/World/StartGameNotification.cs index 2deb8bf687..2e541f5ad7 100644 --- a/OpenRA.Mods.Common/Traits/World/StartGameNotification.cs +++ b/OpenRA.Mods.Common/Traits/World/StartGameNotification.cs @@ -47,7 +47,7 @@ namespace OpenRA.Mods.Common.Traits { if (!world.IsLoadingGameSave) { - Game.Sound.PlayNotification(world.Map.Rules, null, "Speech", info.Notification, world.RenderPlayer == null ? null : world.RenderPlayer.Faction.InternalName); + Game.Sound.PlayNotification(world.Map.Rules, null, "Speech", info.Notification, world.RenderPlayer?.Faction.InternalName); TextNotificationsManager.AddTransientLine(info.TextNotification, null); } } @@ -56,7 +56,7 @@ namespace OpenRA.Mods.Common.Traits { if (!world.IsReplay) { - Game.Sound.PlayNotification(world.Map.Rules, null, "Speech", info.LoadedNotification, world.RenderPlayer == null ? null : world.RenderPlayer.Faction.InternalName); + Game.Sound.PlayNotification(world.Map.Rules, null, "Speech", info.LoadedNotification, world.RenderPlayer?.Faction.InternalName); TextNotificationsManager.AddTransientLine(info.LoadedTextNotification, null); } } @@ -65,7 +65,7 @@ namespace OpenRA.Mods.Common.Traits { if (!world.IsReplay) { - Game.Sound.PlayNotification(world.Map.Rules, null, "Speech", info.SavedNotification, world.RenderPlayer == null ? null : world.RenderPlayer.Faction.InternalName); + Game.Sound.PlayNotification(world.Map.Rules, null, "Speech", info.SavedNotification, world.RenderPlayer?.Faction.InternalName); TextNotificationsManager.AddTransientLine(info.SavedTextNotification, null); } } diff --git a/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs b/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs index e6115e4032..5f5229e82d 100644 --- a/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs +++ b/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs @@ -117,8 +117,7 @@ namespace OpenRA.Mods.Common.UpdateRules if (namedType != null && namedType.IsSubclassOf(typeof(UpdateRule))) return new[] { (UpdateRule)objectCreator.CreateBasic(namedType) }; - var namedPath = Paths.FirstOrDefault(p => p.source == source); - return namedPath != null ? namedPath.Rules(chain) : null; + return Paths.FirstOrDefault(p => p.source == source)?.Rules(chain); } public static IEnumerable KnownPaths { get { return Paths.Select(p => p.source); } } diff --git a/OpenRA.Mods.Common/Widgets/ProductionTabsWidget.cs b/OpenRA.Mods.Common/Widgets/ProductionTabsWidget.cs index 95dde77eb5..bf0441025e 100644 --- a/OpenRA.Mods.Common/Widgets/ProductionTabsWidget.cs +++ b/OpenRA.Mods.Common/Widgets/ProductionTabsWidget.cs @@ -171,7 +171,7 @@ namespace OpenRA.Mods.Common.Widgets set { paletteWidget.Value.CurrentQueue = value; - queueGroup = value != null ? value.Info.Group : null; + queueGroup = value?.Info.Group; // TODO: Scroll tabs so selected queue is visible } diff --git a/OpenRA.Mods.Common/Widgets/RadarWidget.cs b/OpenRA.Mods.Common/Widgets/RadarWidget.cs index c5d9dadc08..0a8622bc2e 100644 --- a/OpenRA.Mods.Common/Widgets/RadarWidget.cs +++ b/OpenRA.Mods.Common/Widgets/RadarWidget.cs @@ -129,7 +129,7 @@ namespace OpenRA.Mods.Common.Widgets { currentPlayer = player; - var newShroud = player != null ? player.Shroud : null; + var newShroud = player?.Shroud; if (newShroud != shroud) { @@ -146,8 +146,7 @@ namespace OpenRA.Mods.Common.Widgets shroud = newShroud; } - var newPlayerRadarTerrain = - currentPlayer != null ? currentPlayer.PlayerActor.TraitOrDefault() : null; + var newPlayerRadarTerrain = currentPlayer?.PlayerActor.TraitOrDefault(); if (forceUpdate || newPlayerRadarTerrain != playerRadarTerrain) {