From 411204b1ac31b9db4780128d6b8247ff37af1d96 Mon Sep 17 00:00:00 2001 From: lanyi Date: Mon, 6 Sep 2021 23:14:21 +0200 Subject: [PATCH] =?UTF-8?q?=E5=8D=87=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AssetEntry.cs | 24 ++++++------- Command.cs | 16 ++++----- Controller.cs | 22 +++++------- CopyableBox.xaml.cs | 2 +- DisposableDispatcherTimer.cs | 2 +- HashCalculator.GUI.csproj | 29 ++++------------ HashCalculator.GUI.sln | 31 +++++++++++++++++ ModXml.cs | 42 +++++++++++------------ Program.cs | 9 ++--- ScriptCompiler.cs | 65 ++++++++++++++++++++++++++++++++++++ Translator.cs | 11 +++--- ViewModel.cs | 44 ++++++++++++------------ 12 files changed, 181 insertions(+), 116 deletions(-) create mode 100644 HashCalculator.GUI.sln create mode 100644 ScriptCompiler.cs diff --git a/AssetEntry.cs b/AssetEntry.cs index fad7918..c708f91 100644 --- a/AssetEntry.cs +++ b/AssetEntry.cs @@ -38,7 +38,7 @@ namespace HashCalculator.GUI { if (element == null) { - throw new ArgumentNullException($"{nameof(element)} is null"); + throw new ArgumentNullException(nameof(element)); } if (element.Name.Namespace != ModXml.EalaAsset) @@ -62,7 +62,7 @@ namespace HashCalculator.GUI { if (asset is null) { - throw new ArgumentNullException($"{nameof(asset)} is null"); + throw new ArgumentNullException(nameof(asset)); } Type = asset.TypeName; Name = asset.InstanceName; @@ -74,13 +74,13 @@ namespace HashCalculator.GUI } } - public bool Equals(AssetEntry entry) + public bool Equals(AssetEntry? entry) { return this == entry; } // override object.Equals - public override bool Equals(object obj) + public override bool Equals(object? obj) { // // See the full list of guidelines at @@ -97,7 +97,7 @@ namespace HashCalculator.GUI return this == entry; } - public static bool operator ==(AssetEntry a, AssetEntry b) + public static bool operator ==(AssetEntry? a, AssetEntry? b) { if (a is null || b is null) { @@ -112,7 +112,7 @@ namespace HashCalculator.GUI return a.Type == b.Type && a.InstanceId == b.InstanceId; } - public static bool operator !=(AssetEntry a, AssetEntry b) + public static bool operator !=(AssetEntry? a, AssetEntry? b) { return !(a == b); } @@ -123,31 +123,31 @@ namespace HashCalculator.GUI return HashCode.Combine(Type, InstanceId); } - public int CompareTo(AssetEntry other) + public int CompareTo(AssetEntry? other) { if (other is null) { - throw new ArgumentNullException($"{nameof(other)} is null"); + throw new ArgumentNullException(nameof(other)); } return string.CompareOrdinal(NameString, other.NameString); } - public static bool operator <(AssetEntry left, AssetEntry right) + public static bool operator <(AssetEntry? left, AssetEntry? right) { return left is null ? right is object : left.CompareTo(right) < 0; } - public static bool operator <=(AssetEntry left, AssetEntry right) + public static bool operator <=(AssetEntry? left, AssetEntry? right) { return left is null || left.CompareTo(right) <= 0; } - public static bool operator >(AssetEntry left, AssetEntry right) + public static bool operator >(AssetEntry? left, AssetEntry? right) { return left is object && left.CompareTo(right) > 0; } - public static bool operator >=(AssetEntry left, AssetEntry right) + public static bool operator >=(AssetEntry? left, AssetEntry? right) { return left is null ? right is null : left.CompareTo(right) >= 0; } diff --git a/Command.cs b/Command.cs index de446aa..3750a86 100644 --- a/Command.cs +++ b/Command.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics.CodeAnalysis; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; @@ -12,8 +11,8 @@ namespace HashCalculator.GUI private readonly Action _onAsyncException; private bool _canExecute = true; - public bool CanExecuteValue - { + public bool CanExecuteValue + { get => _canExecute; set { @@ -27,26 +26,25 @@ namespace HashCalculator.GUI public Command(Func action, Action? onAsyncException = null) { _action = action; - _onAsyncException = onAsyncException ?? (exception => + _onAsyncException = onAsyncException ?? (exception => { MessageBox.Show($"Unhandled async exception in {nameof(Command)}: {exception}"); Application.Current.Shutdown(1); }); } - public bool CanExecute(object parameter) + public bool CanExecute(object? parameter) { return _canExecute; } - [SuppressMessage("Globalization", "CA1303:请不要将文本作为本地化参数传递", Justification = "<挂起>")] - public void Execute(object parameter) + public void Execute(object? parameter) { if (!_canExecute) { return; } - if(!(parameter is T typed)) + if (!(parameter is T typed)) { throw new ArgumentException($"{nameof(parameter)} wrong type"); } @@ -56,7 +54,6 @@ namespace HashCalculator.GUI public Task ExecuteTask(T parameter) => _action(parameter); - [SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")] private async void ExecuteTaskInternal(Task task) { try @@ -115,7 +112,6 @@ namespace HashCalculator.GUI public Task ExecuteTask() => _action(); - [SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")] private async void ExecuteTaskInternal(Task task) { try diff --git a/Controller.cs b/Controller.cs index 0f6264a..ec51f21 100644 --- a/Controller.cs +++ b/Controller.cs @@ -34,7 +34,6 @@ namespace HashCalculator.GUI TracerListener.StartListening(s => action(() => ViewModel.TraceText += s)); } - [SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")] public async Task OnMainInputDecided(InputEntry selected) { try @@ -78,7 +77,6 @@ namespace HashCalculator.GUI } } - [SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")] private static Task CalculateBinaryHash(string filePath, CancellationToken cancel) { return Task.Run(() => @@ -201,7 +199,6 @@ namespace HashCalculator.GUI } } - [SuppressMessage("Reliability", "CA2000:丢失范围之前释放对象", Justification = "<挂起>")] private async Task LoadXml(string path) { await CancelLoadingXml().ConfigureAwait(true); @@ -234,7 +231,6 @@ namespace HashCalculator.GUI }, "SAGE FastHash 计算器 - XML 加载失败…", "XML 文件加载失败,也许,你选择的 XML 文件并不是红警3使用的那种……\r\n").ConfigureAwait(true); } - [SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")] private async Task LoadXmlInternal(string path, CancellationToken token) { var modXml = new ModXml(path, token); @@ -343,14 +339,15 @@ namespace HashCalculator.GUI throw new NotSupportedException(); } - baseDirectory.GetFiles("*.csf"); - var parent = baseDirectory.Parent; - var searchDirectories = - parent.GetDirectories($"{baseDirectory.Name[0]}*") - .Prepend(parent.Parent) - .Prepend(baseDirectory); - searchDirectories = searchDirectories - .Concat(searchDirectories.SelectMany(x => x.GetDirectories("Additional"))); + var searchFrom = new List { baseDirectory }; + if (baseDirectory.Parent is { } parent) + { + searchFrom.AddRange(parent.GetDirectories($"{baseDirectory.Name[0]}*")); + searchFrom.Add(parent); + } + var searchDirectories = new[] { "Additional", "Misc" } + .SelectMany(n => searchFrom.SelectMany(x => x.GetDirectories(n))) + .Concat(searchFrom); var csfs = from directories in searchDirectories from data in directories.GetDirectories("Data") from csf in data.GetFiles("*.csf") @@ -415,7 +412,6 @@ namespace HashCalculator.GUI return VirtualFileSystem.GetFileName(path).StartsWith(what, StringComparison.OrdinalIgnoreCase); } - [SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")] private static async Task ExceptionWrapepr(Func action, string errorTitle, string preErrorMessage) { try diff --git a/CopyableBox.xaml.cs b/CopyableBox.xaml.cs index f5437e2..5303c40 100644 --- a/CopyableBox.xaml.cs +++ b/CopyableBox.xaml.cs @@ -105,7 +105,7 @@ namespace HashCalculator.GUI CloseCommand = new Command(async window => { - CloseCommand.CanExecuteValue = false; + CloseCommand!.CanExecuteValue = false; Notify(nameof(CloseButtonText)); if (_task != null) diff --git a/DisposableDispatcherTimer.cs b/DisposableDispatcherTimer.cs index a666da3..a404eeb 100644 --- a/DisposableDispatcherTimer.cs +++ b/DisposableDispatcherTimer.cs @@ -22,7 +22,7 @@ namespace HashCalculator.GUI { Timer = new DispatcherTimer(interval, DispatcherPriority.Normal, (s, e) => { - if (Timer.IsEnabled && (TimeSinceCreation > wait)) + if (Timer!.IsEnabled && (TimeSinceCreation > wait)) { action(this); } diff --git a/HashCalculator.GUI.csproj b/HashCalculator.GUI.csproj index a60b453..687f37d 100644 --- a/HashCalculator.GUI.csproj +++ b/HashCalculator.GUI.csproj @@ -1,9 +1,8 @@ - - + + true WinExe - net472 - HashCalculator.GUI + net5.0-windows 8.0 enable true @@ -11,30 +10,14 @@ bf77c300-44f6-46ea-be94-f50d6993b55b HashCalculator.GUI.Program - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + - - TechnologyAssembler.Core.dll - - - - - %(ReferenceCopyLocalPaths.DestinationSubDirectory)%(ReferenceCopyLocalPaths.Filename)%(ReferenceCopyLocalPaths.Extension) - - - \ No newline at end of file diff --git a/HashCalculator.GUI.sln b/HashCalculator.GUI.sln new file mode 100644 index 0000000..372ebf0 --- /dev/null +++ b/HashCalculator.GUI.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30907.101 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HashCalculator.GUI", "HashCalculator.GUI.csproj", "{C214AFC4-5969-42D6-9524-7C5AF0719188}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C214AFC4-5969-42D6-9524-7C5AF0719188}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C214AFC4-5969-42D6-9524-7C5AF0719188}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C214AFC4-5969-42D6-9524-7C5AF0719188}.Debug|x86.ActiveCfg = Debug|x86 + {C214AFC4-5969-42D6-9524-7C5AF0719188}.Debug|x86.Build.0 = Debug|x86 + {C214AFC4-5969-42D6-9524-7C5AF0719188}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C214AFC4-5969-42D6-9524-7C5AF0719188}.Release|Any CPU.Build.0 = Release|Any CPU + {C214AFC4-5969-42D6-9524-7C5AF0719188}.Release|x86.ActiveCfg = Release|x86 + {C214AFC4-5969-42D6-9524-7C5AF0719188}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {DCF48A50-EE93-433D-A957-650FEB2779E9} + EndGlobalSection +EndGlobal diff --git a/ModXml.cs b/ModXml.cs index 82694e7..51aec43 100644 --- a/ModXml.cs +++ b/ModXml.cs @@ -44,12 +44,14 @@ namespace HashCalculator.GUI public ModXml(string xmlPath, CancellationToken token) { BaseDirectory = new DirectoryInfo(FindBaseDirectory(xmlPath)); - var allMods = BaseDirectory.Parent; + var allMods = BaseDirectory.Parent + ?? throw new ArgumentException($"{nameof(xmlPath)}'s {nameof(BaseDirectory)} doesn't have a parent"); if (!allMods.Name.Equals("Mods", StringComparison.OrdinalIgnoreCase)) { throw new DirectoryNotFoundException(); } - var allModsParent = allMods.Parent; + var allModsParent = allMods.Parent + ?? throw new ArgumentException($"SDK Mods folder doesn't have a parent"); using var hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32); if (!(hklm.GetValue(RegistryPath) is string sdkRootPath)) { @@ -129,7 +131,9 @@ namespace HashCalculator.GUI } var document = GetFile(fullPath); - if (document.Root.Name != EalaAsset + "AssetDeclaration" && document.Root.Name != "AssetDeclaration") + var rootName = document.Root?.Name + ?? throw new InvalidDataException("Document doesn't have a root"); + if (rootName != EalaAsset + "AssetDeclaration" && rootName != "AssetDeclaration") { throw new NotSupportedException(); } @@ -204,11 +208,13 @@ namespace HashCalculator.GUI private static string FindBaseDirectory(string currentPath) { var file = new FileInfo(currentPath); - if (File.Exists(Path.Combine(file.DirectoryName, "Data", "mod.xml"))) + var directoryName = file.DirectoryName + ?? throw new ArgumentException($"{nameof(currentPath)} doens't have a directory"); + if (File.Exists(Path.Combine(directoryName, "Data", "mod.xml"))) { - return file.DirectoryName; + return directoryName; } - return FindBaseDirectory(file.DirectoryName); + return FindBaseDirectory(directoryName); } } @@ -221,11 +227,11 @@ namespace HashCalculator.GUI Paths = paths; } - public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn) + public override object GetEntity(Uri? absoluteUri, string? role, Type? ofObjectToReturn) { if (absoluteUri == null) { - throw new ArgumentNullException($"{nameof(absoluteUri)} is null"); + throw new ArgumentNullException(nameof(absoluteUri)); } if (ofObjectToReturn != null && ofObjectToReturn != typeof(Stream)) { @@ -234,8 +240,7 @@ namespace HashCalculator.GUI return File.OpenRead(absoluteUri.LocalPath); } - [SuppressMessage("Globalization", "CA1303:请不要将文本作为本地化参数传递", Justification = "<挂起>")] - public override Uri ResolveUri(Uri baseUri, string relativeUri) + public override Uri ResolveUri(Uri? baseUri, string? relativeUri) { if (baseUri == null) { @@ -247,22 +252,13 @@ namespace HashCalculator.GUI } if (relativeUri == null) { - throw new ArgumentNullException($"{nameof(relativeUri)} is null"); + throw new ArgumentNullException(nameof(relativeUri)); } - return new Uri(Path.GetFullPath(ResolvePath(relativeUri, Path.GetDirectoryName(baseUri.LocalPath)))); + var localPath = Path.GetDirectoryName(baseUri.LocalPath) + ?? throw new ArgumentException($"{nameof(baseUri)} doesn't have a local path"); + return new Uri(Path.GetFullPath(ResolvePath(relativeUri, localPath))); } - public override Task GetEntityAsync(Uri absoluteUri, string role, Type ofObjectToReturn) - { - return base.GetEntityAsync(absoluteUri, role, ofObjectToReturn); - } - - public override bool SupportsType(Uri absoluteUri, Type type) - { - return base.SupportsType(absoluteUri, type); - } - - [SuppressMessage("Globalization", "CA1303:请不要将文本作为本地化参数传递", Justification = "<挂起>")] private string ResolvePath(string href, string currentDirectory) { var splitted = href.Split(new[] { ':' }, 2); diff --git a/Program.cs b/Program.cs index f9ab861..779f3b3 100644 --- a/Program.cs +++ b/Program.cs @@ -19,16 +19,17 @@ namespace HashCalculator.GUI } catch(Exception exception) { - ErrorBox($"发生了无法处理的错误:\r\n{exception.ToString()}\r\n可以尝试在百度红警3吧联系岚依"); + ErrorBox($"发生了无法处理的错误:\r\n{exception}\r\n可以尝试在百度红警3吧联系岚依"); throw; } } - private static Assembly OnResolveAssembly(object sender, ResolveEventArgs args) + private static Assembly OnResolveAssembly(object? sender, ResolveEventArgs args) { var executingAssembly = Assembly.GetExecutingAssembly(); var assemblyName = new AssemblyName(args.Name); - var nameString = assemblyName.Name; + var nameString = assemblyName.Name + ?? throw new InvalidOperationException("Assembly does not have an name"); var paths = new[] { $"{nameString}.dll" }.AsEnumerable(); const string resourceExtenstion = ".resources"; @@ -36,7 +37,7 @@ namespace HashCalculator.GUI { paths = paths.Append(nameString.Insert(nameString.Length - resourceExtenstion.Length, ".g")); } - if (!assemblyName.CultureInfo.Equals(CultureInfo.InvariantCulture)) + if (!Equals(assemblyName.CultureInfo, CultureInfo.InvariantCulture)) { paths = paths.Select(x => $"{assemblyName.CultureInfo}\\{x}").Concat(paths); } diff --git a/ScriptCompiler.cs b/ScriptCompiler.cs new file mode 100644 index 0000000..3573b76 --- /dev/null +++ b/ScriptCompiler.cs @@ -0,0 +1,65 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using TechnologyAssembler; + +namespace HashCalculator.GUI +{ + internal class ScriptCompiler + { + private static readonly MetadataReference[] _references = new[] + { + typeof(object), // core + typeof(Trace), // make sure trace is availaible + typeof(Enumerable), // linq + typeof(ScriptCompiler), // this + typeof(TechnologyAssemblerCoreModule) // wed + }.Select(t => MetadataReference.CreateFromFile(t.Assembly.Location)).ToArray(); + + public static IEnumerable<(string Id, string Message)> CheckSyntax(string code) + { + var syntaxTree = CSharpSyntaxTree.ParseText(code); + return syntaxTree.GetDiagnostics().Select(diagnostic => (diagnostic.Id, diagnostic.GetMessage())); + } + + public static bool Compile(string code, object[] arguments, out IEnumerable<(string Id, string Message)> messages) + { + // define source code, then parse it (to the type used for compilation) + var syntaxTree = CSharpSyntaxTree.ParseText(code); + + // define other necessary objects for compilation + var assemblyName = $"Gen{Guid.NewGuid()}.dll"; + + // analyse and generate IL code from syntax tree + var compilation = + CSharpCompilation.Create(assemblyName, + syntaxTrees: new[] { syntaxTree }, + references: _references, + options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + + using var ms = new MemoryStream(); + // write IL code into memory + var result = compilation.Emit(ms); + messages = result.Diagnostics.Select(diagnostic => (diagnostic.Id, diagnostic.GetMessage())); + + if (!result.Success) + { + return false; + } + + // load this 'virtual' DLL so that we can use + ms.Seek(0, SeekOrigin.Begin); + var domain = AppDomain.CreateDomain($"runtime code {assemblyName}"); + var assembly = domain.Load(ms.ToArray()); + // create instance of the desired class and call the desired function + var entryPoint = assembly.EntryPoint + ?? throw new InvalidOperationException("Compiled assembly does not have an entry point"); + entryPoint.Invoke(null, arguments); + return true; + } + } +} diff --git a/Translator.cs b/Translator.cs index 88a0094..cbb3c6f 100644 --- a/Translator.cs +++ b/Translator.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Collections.Concurrent; using System.Threading; using TechnologyAssembler.Core.Language; @@ -14,11 +13,11 @@ namespace HashCalculator.GUI get => Interlocked.CompareExchange(ref _provider, null, null); set { - var provider = value is null - ? null + var provider = value is null + ? null : new CachedCsfTranslationProvider(value); Interlocked.Exchange(ref _provider, provider); - ProviderChanged?.Invoke(null, null); + ProviderChanged?.Invoke(null, EventArgs.Empty); } } @@ -28,7 +27,7 @@ namespace HashCalculator.GUI public static string Translate(string what) { var provider = Provider; - if(provider is null) + if (provider is null) { return $"NoProvider:{what}"; } @@ -50,7 +49,7 @@ namespace HashCalculator.GUI public string GetString(string str) { - if(!_cache.TryGetValue(str, out var value)) + if (!_cache.TryGetValue(str, out var value)) { value = _provider.GetString(str); _cache.TryAdd(str, value); diff --git a/ViewModel.cs b/ViewModel.cs index f8b78e2..b635518 100644 --- a/ViewModel.cs +++ b/ViewModel.cs @@ -1,14 +1,13 @@ -using System; +using Microsoft.Win32; +using System; using System.Collections.Generic; using System.Collections.ObjectModel; -using System.Collections.Specialized; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Runtime.CompilerServices; using System.Threading.Tasks; -using Microsoft.Win32; using TechnologyAssembler.Core.IO; namespace HashCalculator.GUI @@ -61,14 +60,14 @@ namespace HashCalculator.GUI FilterDisplayEntries.Execute(null); } } - + private bool _gameObjectOnly; public bool GameObjectOnly { get => _gameObjectOnly; set => SetField(ref _gameObjectOnly, value); } - + public Command FilterDisplayEntries { get; } private int _totalCount; @@ -133,19 +132,19 @@ namespace HashCalculator.GUI { try { - CancelXml.CanExecuteValue = false; + CancelXml!.CanExecuteValue = false; await controller.CancelLoadingXml().ConfigureAwait(true); } finally { - CancelXml.CanExecuteValue = true; + CancelXml!.CanExecuteValue = true; } }); LoadCsf = new Command(async window => { try { - LoadCsf.CanExecuteValue = false; + LoadCsf!.CanExecuteValue = false; var dialog = new OpenFileDialog { Multiselect = false, @@ -159,7 +158,7 @@ namespace HashCalculator.GUI } finally { - LoadCsf.CanExecuteValue = true; + LoadCsf!.CanExecuteValue = true; } }); FilterDisplayEntries = new Command(() => @@ -221,9 +220,9 @@ namespace HashCalculator.GUI private bool FilterDisplayEntry(AssetEntry entry) { - if(GameObjectOnly) + if (GameObjectOnly) { - if(entry.Type != "GameObject") + if (entry.Type != "GameObject") { return false; } @@ -298,7 +297,7 @@ namespace HashCalculator.GUI { if (value == 0) { - if (Items.Count() <= 1) + if (Items?.Count() <= 1) { value = -1; } @@ -353,13 +352,13 @@ namespace HashCalculator.GUI try { BrowseCommand.CanExecuteValue = false; - SelectCommand.CanExecuteValue = false; + SelectCommand!.CanExecuteValue = false; await controller.OnMainInputDecided(SelectedItem).ConfigureAwait(true); } finally { BrowseCommand.CanExecuteValue = true; - SelectCommand.CanExecuteValue = true; + SelectCommand!.CanExecuteValue = true; SelectedIndex = -1; } }); @@ -417,7 +416,7 @@ namespace HashCalculator.GUI base.Text = value; if (value != SelectedItem?.ToString()) { - if(AllManifests != null) + if (AllManifests != null) { UpdateList(value); } @@ -448,7 +447,6 @@ namespace HashCalculator.GUI public Command SelectCommand { get; } - [SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")] public BigInputViewModel(Controller controller) { SelectCommand = new Command(async viewModel => @@ -456,7 +454,7 @@ namespace HashCalculator.GUI var mainInput = viewModel.MainInput; try { - SelectCommand.CanExecuteValue = false; + SelectCommand!.CanExecuteValue = false; mainInput.BrowseCommand.CanExecuteValue = false; mainInput.SelectCommand.CanExecuteValue = false; LastProcessedManifest = SelectedItem; @@ -464,14 +462,14 @@ namespace HashCalculator.GUI } catch (Exception exception) { - CopyableBox.ShowDialog("SAGE FastHash 计算器的错误" , _ => - { - return Task.FromResult($"在加载 manifest 时发生错误:{exception}"); - }); + CopyableBox.ShowDialog("SAGE FastHash 计算器的错误", _ => + { + return Task.FromResult($"在加载 manifest 时发生错误:{exception}"); + }); } finally { - SelectCommand.CanExecuteValue = true; + SelectCommand!.CanExecuteValue = true; mainInput.BrowseCommand.CanExecuteValue = true; mainInput.SelectCommand.CanExecuteValue = true; } @@ -526,7 +524,7 @@ namespace HashCalculator.GUI { try { - foreach(var i in Enumerable.Range(0, base.Count).Reverse()) + foreach (var i in Enumerable.Range(0, base.Count).Reverse()) { var item = base[i]; if (ifRemove(item))