From 7585d45d041650e09118a10f6c9ac45298e406a6 Mon Sep 17 00:00:00 2001 From: walterlv Date: Sat, 27 Apr 2024 10:15:09 +0800 Subject: [PATCH 01/23] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E5=88=B0=E6=9C=80?= =?UTF-8?q?=E6=96=B0=E7=9A=84=E9=A1=B9=E7=9B=AE=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 44 +++++++++++++++++-- Directory.Build.props | 22 +++++++--- ...etCampus.LatestCSharpFeatures.Tests.csproj | 8 ++++ 3 files changed, 63 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 9491a2f..1cd7ff5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ -## Ignore Visual Studio temporary files, build results, and +## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. ## -## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore +## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore # User-specific files *.rsuser @@ -29,7 +29,6 @@ x86/ bld/ [Bb]in/ [Oo]bj/ -[Oo]ut/ [Ll]og/ [Ll]ogs/ @@ -91,6 +90,7 @@ StyleCopReport.xml *.tmp_proj *_wpftmp.csproj *.log +*.tlog *.vspscc *.vssscc .builds @@ -294,6 +294,17 @@ node_modules/ # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) *.vbw +# Visual Studio 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files +*.ncb +*.aps + # Visual Studio LightSwitch build output **/*.HTMLClient/GeneratedArtifacts **/*.DesktopClient/GeneratedArtifacts @@ -350,6 +361,9 @@ ASALocalRun/ # Local History for Visual Studio .localhistory/ +# Visual Studio History (VSHistory) files +.vshistory/ + # BeatPulse healthcheck temp database healthchecksdb @@ -360,4 +374,26 @@ MigrationBackup/ .ionide/ # Fody - auto-generated XML schema -FodyWeavers.xsd \ No newline at end of file +FodyWeavers.xsd + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +.idea/ +*.sln.iml diff --git a/Directory.Build.props b/Directory.Build.props index 271e9dd..61801d0 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -2,25 +2,33 @@ + - latest + enable + true True + $(MSBuildThisFileDirectory)artifacts + $(MSBuildThisFileDirectory) + + $(NoWarn);NETSDK1138;NU5100 + - $(MSBuildThisFileDirectory)bin\$(Configuration) - dotnet campus(.NET 职业技术学院) + + + 提供统一的日志记录方法。使用源生成器允许库的作者在不依赖本日志库的情况下完成日志的记录,并且还能对接到产品中完成日志的统一输出。 dotnet-campus + dotnet campus(.NET 职业技术学院) + Copyright © 2023-2024 dotnet campus, All Rights Reserved. + git https://github.com/dotnet-campus/dotnetCampus.LatestCSharpFeatures https://github.com/dotnet-campus/dotnetCampus.LatestCSharpFeatures - git - Copyright © 2023 dotnet campus, All Rights Reserved. - @@ -28,4 +36,4 @@ - \ No newline at end of file + diff --git a/tests/dotnetCampus.LatestCSharpFeatures.Tests/dotnetCampus.LatestCSharpFeatures.Tests.csproj b/tests/dotnetCampus.LatestCSharpFeatures.Tests/dotnetCampus.LatestCSharpFeatures.Tests.csproj index d2d03ce..329fd93 100644 --- a/tests/dotnetCampus.LatestCSharpFeatures.Tests/dotnetCampus.LatestCSharpFeatures.Tests.csproj +++ b/tests/dotnetCampus.LatestCSharpFeatures.Tests/dotnetCampus.LatestCSharpFeatures.Tests.csproj @@ -8,6 +8,14 @@ true + + + $(NoWarn);NETSDK1138;NU1504 + + From 9f0d1cc77200140b3a071a8eddb8bb12b744f32f Mon Sep 17 00:00:00 2001 From: walterlv Date: Sat, 27 Apr 2024 10:31:54 +0800 Subject: [PATCH 02/23] =?UTF-8?q?=E5=88=A0=E9=99=A4=E4=B8=8D=E6=83=B3?= =?UTF-8?q?=E5=86=8D=E7=BB=B4=E6=8A=A4=E7=9A=84=E5=AD=90=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dotnetCampus.LatestCSharpFeatures.sln | 59 - .../dotnetCampus.IsExternalInit.Source.csproj | 14 - src/dotnetCampus.IsExternalInit/_._ | 0 .../dotnetCampus.IsExternalInit.csproj | 25 - ...dedSourceFile.cs => EmbeddedSourceFile.cs} | 7 +- .../Utils/EmbededSourceFiles.cs | 3 +- ...ampus.LatestCSharpFeatures.Analyzer.csproj | 10 +- ...tCampus.LatestCSharpFeatures.Source.csproj | 22 - .../ExternalInit}/IsExternalInit.cs | 4 +- .../Nullable}/Nullable.cs | 2 - .../Required}/RequiredMemberAttribute.cs | 4 +- .../Required}/SetsRequiredMembersAttribute.cs | 0 .../ValueTuple/TupleElementNamesAttribute.cs | 66 + .../ValueTuple/ValueTuple.cs | 2362 +++++++++++++++++ src/dotnetCampus.LatestCSharpFeatures/_._ | 0 .../dotnetCampus.LatestCSharpFeatures.csproj | 17 +- .../dotnetCampus.Nullable.Source.csproj | 14 - src/dotnetCampus.Nullable/_._ | 0 .../dotnetCampus.Nullable.csproj | 25 - .../dotnetCampus.Required.Source.csproj | 22 - src/dotnetCampus.Required/_._ | 0 .../dotnetCampus.Required.csproj | 29 - 22 files changed, 2444 insertions(+), 241 deletions(-) delete mode 100644 src/dotnetCampus.IsExternalInit.Source/dotnetCampus.IsExternalInit.Source.csproj delete mode 100644 src/dotnetCampus.IsExternalInit/_._ delete mode 100644 src/dotnetCampus.IsExternalInit/dotnetCampus.IsExternalInit.csproj rename src/dotnetCampus.LatestCSharpFeatures.Analyzer/Utils/{EmbededSourceFile.cs => EmbeddedSourceFile.cs} (80%) delete mode 100644 src/dotnetCampus.LatestCSharpFeatures.Source/dotnetCampus.LatestCSharpFeatures.Source.csproj rename src/{dotnetCampus.IsExternalInit.Source => dotnetCampus.LatestCSharpFeatures/ExternalInit}/IsExternalInit.cs (84%) rename src/{dotnetCampus.Nullable.Source => dotnetCampus.LatestCSharpFeatures/Nullable}/Nullable.cs (98%) rename src/{dotnetCampus.Required.Source => dotnetCampus.LatestCSharpFeatures/Required}/RequiredMemberAttribute.cs (95%) rename src/{dotnetCampus.Required.Source => dotnetCampus.LatestCSharpFeatures/Required}/SetsRequiredMembersAttribute.cs (100%) create mode 100644 src/dotnetCampus.LatestCSharpFeatures/ValueTuple/TupleElementNamesAttribute.cs create mode 100644 src/dotnetCampus.LatestCSharpFeatures/ValueTuple/ValueTuple.cs delete mode 100644 src/dotnetCampus.LatestCSharpFeatures/_._ delete mode 100644 src/dotnetCampus.Nullable.Source/dotnetCampus.Nullable.Source.csproj delete mode 100644 src/dotnetCampus.Nullable/_._ delete mode 100644 src/dotnetCampus.Nullable/dotnetCampus.Nullable.csproj delete mode 100644 src/dotnetCampus.Required.Source/dotnetCampus.Required.Source.csproj delete mode 100644 src/dotnetCampus.Required/_._ delete mode 100644 src/dotnetCampus.Required/dotnetCampus.Required.csproj diff --git a/dotnetCampus.LatestCSharpFeatures.sln b/dotnetCampus.LatestCSharpFeatures.sln index c1d0bb8..573218d 100644 --- a/dotnetCampus.LatestCSharpFeatures.sln +++ b/dotnetCampus.LatestCSharpFeatures.sln @@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.6.33712.159 MinimumVisualStudioVersion = 15.0.26124.0 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnetCampus.Nullable", "src\dotnetCampus.Nullable\dotnetCampus.Nullable.csproj", "{2ECF1CEB-070E-4933-93C4-F7FD42D8693C}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{8A6F61D3-076F-4B75-80A1-FF377AC69D73}" ProjectSection(SolutionItems) = preProject .gitattributes = .gitattributes @@ -15,28 +13,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{8A6F61D3 build\Version.props = build\Version.props EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnetCampus.IsExternalInit", "src\dotnetCampus.IsExternalInit\dotnetCampus.IsExternalInit.csproj", "{0DDC38EF-851E-49E7-B72A-DF46E44E3586}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnetCampus.IsExternalInit.Source", "src\dotnetCampus.IsExternalInit.Source\dotnetCampus.IsExternalInit.Source.csproj", "{94E8B753-81BF-44DC-A8D6-AC1D1FE54244}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnetCampus.Required", "src\dotnetCampus.Required\dotnetCampus.Required.csproj", "{6ED76C7A-A16A-45A5-BC1F-91A880839C31}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnetCampus.Required.Source", "src\dotnetCampus.Required.Source\dotnetCampus.Required.Source.csproj", "{4EBF62CB-613E-4496-B890-B1F433ED7581}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnetCampus.LatestCSharpFeatures", "src\dotnetCampus.LatestCSharpFeatures\dotnetCampus.LatestCSharpFeatures.csproj", "{D0B0F7EB-3C81-45C4-BB47-5DCB16F2EA55}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnetCampus.Nullable.Source", "src\dotnetCampus.Nullable.Source\dotnetCampus.Nullable.Source.csproj", "{72163C73-CBC5-4CB5-BDDF-769B7AFD6FAB}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnetCampus.LatestCSharpFeatures.Source", "src\dotnetCampus.LatestCSharpFeatures.Source\dotnetCampus.LatestCSharpFeatures.Source.csproj", "{16D75C29-3176-4CFD-A1B5-B5F24876B038}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "IsExternalInit", "IsExternalInit", "{4E06689B-E73A-4A04-AAA0-7959A6EC06E6}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Nullable", "Nullable", "{CCAAE7A8-1879-4F67-98AA-D837C80227A2}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Required", "Required", "{F0CBB519-BB38-4104-B840-4076BB206E36}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{CAB44C21-D58C-4732-B9D8-60B1DAE82BEF}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{878C1D77-0A77-44BD-847E-164188B10677}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnetCampus.LatestCSharpFeatures.Tests", "tests\dotnetCampus.LatestCSharpFeatures.Tests\dotnetCampus.LatestCSharpFeatures.Tests.csproj", "{D10BF09A-FDF3-43F0-BD54-49A73554CDAB}" @@ -49,38 +27,10 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {2ECF1CEB-070E-4933-93C4-F7FD42D8693C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2ECF1CEB-070E-4933-93C4-F7FD42D8693C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2ECF1CEB-070E-4933-93C4-F7FD42D8693C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2ECF1CEB-070E-4933-93C4-F7FD42D8693C}.Release|Any CPU.Build.0 = Release|Any CPU - {0DDC38EF-851E-49E7-B72A-DF46E44E3586}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0DDC38EF-851E-49E7-B72A-DF46E44E3586}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0DDC38EF-851E-49E7-B72A-DF46E44E3586}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0DDC38EF-851E-49E7-B72A-DF46E44E3586}.Release|Any CPU.Build.0 = Release|Any CPU - {94E8B753-81BF-44DC-A8D6-AC1D1FE54244}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {94E8B753-81BF-44DC-A8D6-AC1D1FE54244}.Debug|Any CPU.Build.0 = Debug|Any CPU - {94E8B753-81BF-44DC-A8D6-AC1D1FE54244}.Release|Any CPU.ActiveCfg = Release|Any CPU - {94E8B753-81BF-44DC-A8D6-AC1D1FE54244}.Release|Any CPU.Build.0 = Release|Any CPU - {6ED76C7A-A16A-45A5-BC1F-91A880839C31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6ED76C7A-A16A-45A5-BC1F-91A880839C31}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6ED76C7A-A16A-45A5-BC1F-91A880839C31}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6ED76C7A-A16A-45A5-BC1F-91A880839C31}.Release|Any CPU.Build.0 = Release|Any CPU - {4EBF62CB-613E-4496-B890-B1F433ED7581}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4EBF62CB-613E-4496-B890-B1F433ED7581}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4EBF62CB-613E-4496-B890-B1F433ED7581}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4EBF62CB-613E-4496-B890-B1F433ED7581}.Release|Any CPU.Build.0 = Release|Any CPU {D0B0F7EB-3C81-45C4-BB47-5DCB16F2EA55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D0B0F7EB-3C81-45C4-BB47-5DCB16F2EA55}.Debug|Any CPU.Build.0 = Debug|Any CPU {D0B0F7EB-3C81-45C4-BB47-5DCB16F2EA55}.Release|Any CPU.ActiveCfg = Release|Any CPU {D0B0F7EB-3C81-45C4-BB47-5DCB16F2EA55}.Release|Any CPU.Build.0 = Release|Any CPU - {72163C73-CBC5-4CB5-BDDF-769B7AFD6FAB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {72163C73-CBC5-4CB5-BDDF-769B7AFD6FAB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {72163C73-CBC5-4CB5-BDDF-769B7AFD6FAB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {72163C73-CBC5-4CB5-BDDF-769B7AFD6FAB}.Release|Any CPU.Build.0 = Release|Any CPU - {16D75C29-3176-4CFD-A1B5-B5F24876B038}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {16D75C29-3176-4CFD-A1B5-B5F24876B038}.Debug|Any CPU.Build.0 = Debug|Any CPU - {16D75C29-3176-4CFD-A1B5-B5F24876B038}.Release|Any CPU.ActiveCfg = Release|Any CPU - {16D75C29-3176-4CFD-A1B5-B5F24876B038}.Release|Any CPU.Build.0 = Release|Any CPU {D10BF09A-FDF3-43F0-BD54-49A73554CDAB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D10BF09A-FDF3-43F0-BD54-49A73554CDAB}.Debug|Any CPU.Build.0 = Debug|Any CPU {D10BF09A-FDF3-43F0-BD54-49A73554CDAB}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -94,15 +44,6 @@ Global HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {2ECF1CEB-070E-4933-93C4-F7FD42D8693C} = {CCAAE7A8-1879-4F67-98AA-D837C80227A2} - {0DDC38EF-851E-49E7-B72A-DF46E44E3586} = {4E06689B-E73A-4A04-AAA0-7959A6EC06E6} - {94E8B753-81BF-44DC-A8D6-AC1D1FE54244} = {4E06689B-E73A-4A04-AAA0-7959A6EC06E6} - {6ED76C7A-A16A-45A5-BC1F-91A880839C31} = {F0CBB519-BB38-4104-B840-4076BB206E36} - {4EBF62CB-613E-4496-B890-B1F433ED7581} = {F0CBB519-BB38-4104-B840-4076BB206E36} - {72163C73-CBC5-4CB5-BDDF-769B7AFD6FAB} = {CCAAE7A8-1879-4F67-98AA-D837C80227A2} - {4E06689B-E73A-4A04-AAA0-7959A6EC06E6} = {CAB44C21-D58C-4732-B9D8-60B1DAE82BEF} - {CCAAE7A8-1879-4F67-98AA-D837C80227A2} = {CAB44C21-D58C-4732-B9D8-60B1DAE82BEF} - {F0CBB519-BB38-4104-B840-4076BB206E36} = {CAB44C21-D58C-4732-B9D8-60B1DAE82BEF} {D10BF09A-FDF3-43F0-BD54-49A73554CDAB} = {878C1D77-0A77-44BD-847E-164188B10677} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution diff --git a/src/dotnetCampus.IsExternalInit.Source/dotnetCampus.IsExternalInit.Source.csproj b/src/dotnetCampus.IsExternalInit.Source/dotnetCampus.IsExternalInit.Source.csproj deleted file mode 100644 index 5d8588f..0000000 --- a/src/dotnetCampus.IsExternalInit.Source/dotnetCampus.IsExternalInit.Source.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - - net5.0;netcoreapp3.0;netstandard2.0;net40 - System.Diagnostics.CodeAnalysis - dotnetCampus.IsExternalInit - If you use C# 9.0 or later and want to use record types, this '.Source' library adds internal IsExternalInit attribute support to your project. This confines the new language feature to the project itself without affecting other projects that reference it. - - - - - - - \ No newline at end of file diff --git a/src/dotnetCampus.IsExternalInit/_._ b/src/dotnetCampus.IsExternalInit/_._ deleted file mode 100644 index e69de29..0000000 diff --git a/src/dotnetCampus.IsExternalInit/dotnetCampus.IsExternalInit.csproj b/src/dotnetCampus.IsExternalInit/dotnetCampus.IsExternalInit.csproj deleted file mode 100644 index 6d8be72..0000000 --- a/src/dotnetCampus.IsExternalInit/dotnetCampus.IsExternalInit.csproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - net5.0;netcoreapp3.0;netstandard2.0;net40 - true - System.Diagnostics.CodeAnalysis - If you use C# 9.0 or later and want to use record types, this library adds public IsExternalInit attribute support for your project, allowing the new language feature to be propagated to other projects that reference this one. - $(DefineConstants);USE_PUBLIC_LATEST_CSHARP_FEATURES - - - - false - - - - - - - - - - - - - diff --git a/src/dotnetCampus.LatestCSharpFeatures.Analyzer/Utils/EmbededSourceFile.cs b/src/dotnetCampus.LatestCSharpFeatures.Analyzer/Utils/EmbeddedSourceFile.cs similarity index 80% rename from src/dotnetCampus.LatestCSharpFeatures.Analyzer/Utils/EmbededSourceFile.cs rename to src/dotnetCampus.LatestCSharpFeatures.Analyzer/Utils/EmbeddedSourceFile.cs index 2ba335b..fa1b58f 100644 --- a/src/dotnetCampus.LatestCSharpFeatures.Analyzer/Utils/EmbededSourceFile.cs +++ b/src/dotnetCampus.LatestCSharpFeatures.Analyzer/Utils/EmbeddedSourceFile.cs @@ -1,10 +1,11 @@ namespace dotnetCampus.LatestCSharpFeatures.Analyzer; + /// /// 嵌入的文本资源的数据。 /// -/// 文件在嵌入的资源中的名称。 +/// 文件在嵌入的资源中的名称。 /// 文件的文本内容。 -internal readonly record struct EmbededSourceFile(string EmbededName, string Content) +internal readonly record struct EmbeddedSourceFile(string EmbeddedName, string Content) { /// /// 根据资源名称猜测文件的无扩展名的名称。 @@ -12,7 +13,7 @@ internal readonly record struct EmbededSourceFile(string EmbededName, string Con /// 无扩展名的文件名。 public ReadOnlySpan GuessFileNameWithoutExtension() { - var span = EmbededName.AsSpan(); + var span = EmbeddedName.AsSpan(); var secondLastDotIndex = 0; var lastDotIndex = 0; for (var i = 0; i < span.Length; i++) diff --git a/src/dotnetCampus.LatestCSharpFeatures.Analyzer/Utils/EmbededSourceFiles.cs b/src/dotnetCampus.LatestCSharpFeatures.Analyzer/Utils/EmbededSourceFiles.cs index 339e99c..898e8c3 100644 --- a/src/dotnetCampus.LatestCSharpFeatures.Analyzer/Utils/EmbededSourceFiles.cs +++ b/src/dotnetCampus.LatestCSharpFeatures.Analyzer/Utils/EmbededSourceFiles.cs @@ -1,6 +1,7 @@ using System.Reflection; namespace dotnetCampus.LatestCSharpFeatures.Analyzer; + /// /// 从嵌入的资源中寻找源代码。 /// @@ -11,7 +12,7 @@ internal static class EmbededSourceFiles /// /// 资源文件夹名称。 /// - internal static IEnumerable Enumerate(string folderName) + internal static IEnumerable Enumerate(string folderName) { // 资源字符串格式为:"{Namespace}.{Folder}.{filename}.{Extension}" var desiredFolder = $"{typeof(EmbededSourceFiles).Namespace}.{folderName}"; diff --git a/src/dotnetCampus.LatestCSharpFeatures.Analyzer/dotnetCampus.LatestCSharpFeatures.Analyzer.csproj b/src/dotnetCampus.LatestCSharpFeatures.Analyzer/dotnetCampus.LatestCSharpFeatures.Analyzer.csproj index 2e31557..ca1c98d 100644 --- a/src/dotnetCampus.LatestCSharpFeatures.Analyzer/dotnetCampus.LatestCSharpFeatures.Analyzer.csproj +++ b/src/dotnetCampus.LatestCSharpFeatures.Analyzer/dotnetCampus.LatestCSharpFeatures.Analyzer.csproj @@ -14,12 +14,10 @@ - - - - - - + + + + diff --git a/src/dotnetCampus.LatestCSharpFeatures.Source/dotnetCampus.LatestCSharpFeatures.Source.csproj b/src/dotnetCampus.LatestCSharpFeatures.Source/dotnetCampus.LatestCSharpFeatures.Source.csproj deleted file mode 100644 index a44e7c6..0000000 --- a/src/dotnetCampus.LatestCSharpFeatures.Source/dotnetCampus.LatestCSharpFeatures.Source.csproj +++ /dev/null @@ -1,22 +0,0 @@ - - - - net5.0;netcoreapp3.0;netstandard2.0;net40 - true - System.Diagnostics.CodeAnalysis - This comprehensive package provides support for the latest C# language features in your project, enabling older .NET projects to use newer C# language constructs. Currently includes support for 'nullable', 'init', and 'required' keywords. The types introduced are internal, confining these features to the project itself without affecting other projects that reference it. By installing this package, you get all the newest C# features in one place, eliminating the need to install separate packages for each feature. Future updates will include more new features as they are released. - false - - - - - - - - - - - - - - diff --git a/src/dotnetCampus.IsExternalInit.Source/IsExternalInit.cs b/src/dotnetCampus.LatestCSharpFeatures/ExternalInit/IsExternalInit.cs similarity index 84% rename from src/dotnetCampus.IsExternalInit.Source/IsExternalInit.cs rename to src/dotnetCampus.LatestCSharpFeatures/ExternalInit/IsExternalInit.cs index 9f6856a..923396b 100644 --- a/src/dotnetCampus.IsExternalInit.Source/IsExternalInit.cs +++ b/src/dotnetCampus.LatestCSharpFeatures/ExternalInit/IsExternalInit.cs @@ -1,7 +1,5 @@ #if NET5_0_OR_GREATER -// .NET 5.0 开始已包含 IsExternalInit。 #else -// 旧框架需要包含 IsExternalInit。 using System.ComponentModel; namespace System.Runtime.CompilerServices @@ -21,4 +19,4 @@ static class IsExternalInit { } } -#endif \ No newline at end of file +#endif diff --git a/src/dotnetCampus.Nullable.Source/Nullable.cs b/src/dotnetCampus.LatestCSharpFeatures/Nullable/Nullable.cs similarity index 98% rename from src/dotnetCampus.Nullable.Source/Nullable.cs rename to src/dotnetCampus.LatestCSharpFeatures/Nullable/Nullable.cs index a32bb1a..b785da3 100644 --- a/src/dotnetCampus.Nullable.Source/Nullable.cs +++ b/src/dotnetCampus.LatestCSharpFeatures/Nullable/Nullable.cs @@ -1,7 +1,6 @@ namespace System.Diagnostics.CodeAnalysis { #if NETCOREAPP3_0 || NETCOREAPP3_1 || NET5_0_OR_GREATER - // 新框架都包含基本的 Nullable Attributes。 #else /// /// 标记一个不可空的输入实际上是可以传入 null 的。 @@ -158,7 +157,6 @@ sealed class DoesNotReturnIfAttribute : Attribute #endif #if NET5_0_OR_GREATER - // .NET 5.0 开始已包含更多 Nullable Attributes。 #else /// /// 调用了此方法后,即可保证列表中所列出的字段和属性成员将不会为 null。 diff --git a/src/dotnetCampus.Required.Source/RequiredMemberAttribute.cs b/src/dotnetCampus.LatestCSharpFeatures/Required/RequiredMemberAttribute.cs similarity index 95% rename from src/dotnetCampus.Required.Source/RequiredMemberAttribute.cs rename to src/dotnetCampus.LatestCSharpFeatures/Required/RequiredMemberAttribute.cs index 38ae474..610a8d1 100644 --- a/src/dotnetCampus.Required.Source/RequiredMemberAttribute.cs +++ b/src/dotnetCampus.LatestCSharpFeatures/Required/RequiredMemberAttribute.cs @@ -1,7 +1,5 @@ #if NET7_0_OR_GREATER -// .NET 7.0 开始已包含 required。 #else -// 旧框架需要包含 required。 namespace System.Runtime.CompilerServices { /// @@ -54,4 +52,4 @@ public CompilerFeatureRequiredAttribute(string featureName) public const string RequiredMembers = nameof(RequiredMembers); } } -#endif \ No newline at end of file +#endif diff --git a/src/dotnetCampus.Required.Source/SetsRequiredMembersAttribute.cs b/src/dotnetCampus.LatestCSharpFeatures/Required/SetsRequiredMembersAttribute.cs similarity index 100% rename from src/dotnetCampus.Required.Source/SetsRequiredMembersAttribute.cs rename to src/dotnetCampus.LatestCSharpFeatures/Required/SetsRequiredMembersAttribute.cs diff --git a/src/dotnetCampus.LatestCSharpFeatures/ValueTuple/TupleElementNamesAttribute.cs b/src/dotnetCampus.LatestCSharpFeatures/ValueTuple/TupleElementNamesAttribute.cs new file mode 100644 index 0000000..2a56706 --- /dev/null +++ b/src/dotnetCampus.LatestCSharpFeatures/ValueTuple/TupleElementNamesAttribute.cs @@ -0,0 +1,66 @@ +#if NETSTANDARD2_0_OR_GREATER || NETCOREAPP3_0 || NETCOREAPP3_1 || NET5_0_OR_GREATER +#else +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Runtime.CompilerServices +{ + using System.Collections.Generic; + + /// + /// Indicates that the use of on a member is meant to be treated as a tuple with element names. + /// + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue | AttributeTargets.Class | AttributeTargets.Struct )] + public sealed class TupleElementNamesAttribute : Attribute + { + private readonly string[] _transformNames; + + /// + /// Initializes a new instance of the class. + /// + /// + /// Specifies, in a prefix traversal of a type's + /// construction, which occurrences are meant to + /// carry element names. + /// + /// + /// This constructor is meant to be used on types that are built on an underlying + /// occurrence of that is meant to carry element names. + /// For instance, if C is a generic type with two type parameters, then a + /// use of the constructed type C{, + /// might be intended to treat the first type argument as a tuple with element names + /// and the second as a tuple without element names. In which case, the appropriate attribute + /// specification should use transformNames value of { "name1", "name2", null }. + /// + public TupleElementNamesAttribute(string[] transformNames) + { + if (transformNames == null) + { + throw new ArgumentNullException(nameof(transformNames)); + } + + _transformNames = transformNames; + } + + /// + /// Initializes a new instance of the class. + /// + /// + /// When is created with this constructor, + /// it can be omitted instead. + /// + public TupleElementNamesAttribute() + { + _transformNames = new string[] { }; + } + + /// + /// Specifies, in a prefix traversal of a type's + /// construction, which occurrences are meant to + /// carry element names. + /// + public IList TransformNames => _transformNames; + } +} +#endif diff --git a/src/dotnetCampus.LatestCSharpFeatures/ValueTuple/ValueTuple.cs b/src/dotnetCampus.LatestCSharpFeatures/ValueTuple/ValueTuple.cs new file mode 100644 index 0000000..d18c7ea --- /dev/null +++ b/src/dotnetCampus.LatestCSharpFeatures/ValueTuple/ValueTuple.cs @@ -0,0 +1,2362 @@ +#if NETSTANDARD2_0_OR_GREATER || NETCOREAPP3_0 || NETCOREAPP3_1 || NET5_0_OR_GREATER +#else +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Numerics.Hashing +{ + internal static class HashHelpers + { + public static readonly int RandomSeed = new Random().Next(Int32.MinValue, Int32.MaxValue); + + public static int Combine(int h1, int h2) + { + // RyuJIT optimizes this to use the ROL instruction + // Related GitHub pull request: dotnet/coreclr#1830 + uint rol5 = ((uint)h1 << 5) | ((uint)h1 >> 27); + return ((int)rol5 + h1) ^ h2; + } + } +} + +namespace System.Runtime.CompilerServices +{ + /// + /// This interface is required for types that want to be indexed into by dynamic patterns. + /// + public interface ITuple + { + /// + /// The number of positions in this data structure. + /// + int Length { get; } + + /// + /// Get the element at position . + /// + object this[int index] { get; } + } +} + +namespace System +{ + using System.Collections; + using System.Collections.Generic; + using System.Diagnostics.Contracts; + using System.Runtime.InteropServices; + using System.Runtime.CompilerServices; + using HashHelpers = System.Numerics.Hashing.HashHelpers; + + /// + /// Helper so we can call some tuple methods recursively without knowing the underlying types. + /// + internal interface IValueTupleInternal : ITuple + { + int GetHashCode(IEqualityComparer comparer); + string ToStringEnd(); + } + + /// + /// The ValueTuple types (from arity 0 to 8) comprise the runtime implementation that underlies tuples in C# and struct tuples in F#. + /// Aside from created via language syntax, they are most easily created via the ValueTuple.Create factory methods. + /// The System.ValueTuple types differ from the System.Tuple types in that: + /// - they are structs rather than classes, + /// - they are mutable rather than readonly, and + /// - their members (such as Item1, Item2, etc) are fields rather than properties. + /// + [Serializable] + public struct ValueTuple + : IEquatable, IStructuralEquatable, IStructuralComparable, IComparable, IComparable, IValueTupleInternal, ITuple + { + /// + /// Returns a value that indicates whether the current instance is equal to a specified object. + /// + /// The object to compare with this instance. + /// if is a . + public override bool Equals(object obj) + { + return obj is ValueTuple; + } + + /// Returns a value indicating whether this instance is equal to a specified value. + /// An instance to compare to this instance. + /// true if has the same value as this instance; otherwise, false. + public bool Equals(ValueTuple other) + { + return true; + } + + bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) + { + return other is ValueTuple; + } + + int IComparable.CompareTo(object other) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException(); + } + + return 0; + } + + /// Compares this instance to a specified instance and returns an indication of their relative values. + /// An instance to compare. + /// + /// A signed number indicating the relative values of this instance and . + /// Returns less than zero if this instance is less than , zero if this + /// instance is equal to , and greater than zero if this instance is greater + /// than . + /// + public int CompareTo(ValueTuple other) + { + return 0; + } + + int IStructuralComparable.CompareTo(object other, IComparer comparer) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException(); + } + + return 0; + } + + /// Returns the hash code for this instance. + /// A 32-bit signed integer hash code. + public override int GetHashCode() + { + return 0; + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) + { + return 0; + } + + int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) + { + return 0; + } + + /// + /// Returns a string that represents the value of this instance. + /// + /// The string representation of this instance. + /// + /// The string returned by this method takes the form (). + /// + public override string ToString() + { + return "()"; + } + + string IValueTupleInternal.ToStringEnd() + { + return ")"; + } + + /// + /// The number of positions in this data structure. + /// + int ITuple.Length => 0; + + /// + /// Get the element at position . + /// + object ITuple.this[int index] + { + get + { + throw new IndexOutOfRangeException(); + } + } + + /// Creates a new struct 0-tuple. + /// A 0-tuple. + public static ValueTuple Create() => + new ValueTuple(); + + /// Creates a new struct 1-tuple, or singleton. + /// The type of the first component of the tuple. + /// The value of the first component of the tuple. + /// A 1-tuple (singleton) whose value is (item1). + public static ValueTuple Create(T1 item1) => + new ValueTuple(item1); + + /// Creates a new struct 2-tuple, or pair. + /// The type of the first component of the tuple. + /// The type of the second component of the tuple. + /// The value of the first component of the tuple. + /// The value of the second component of the tuple. + /// A 2-tuple (pair) whose value is (item1, item2). + public static ValueTuple Create(T1 item1, T2 item2) => + new ValueTuple(item1, item2); + + /// Creates a new struct 3-tuple, or triple. + /// The type of the first component of the tuple. + /// The type of the second component of the tuple. + /// The type of the third component of the tuple. + /// The value of the first component of the tuple. + /// The value of the second component of the tuple. + /// The value of the third component of the tuple. + /// A 3-tuple (triple) whose value is (item1, item2, item3). + public static ValueTuple Create(T1 item1, T2 item2, T3 item3) => + new ValueTuple(item1, item2, item3); + + /// Creates a new struct 4-tuple, or quadruple. + /// The type of the first component of the tuple. + /// The type of the second component of the tuple. + /// The type of the third component of the tuple. + /// The type of the fourth component of the tuple. + /// The value of the first component of the tuple. + /// The value of the second component of the tuple. + /// The value of the third component of the tuple. + /// The value of the fourth component of the tuple. + /// A 4-tuple (quadruple) whose value is (item1, item2, item3, item4). + public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4) => + new ValueTuple(item1, item2, item3, item4); + + /// Creates a new struct 5-tuple, or quintuple. + /// The type of the first component of the tuple. + /// The type of the second component of the tuple. + /// The type of the third component of the tuple. + /// The type of the fourth component of the tuple. + /// The type of the fifth component of the tuple. + /// The value of the first component of the tuple. + /// The value of the second component of the tuple. + /// The value of the third component of the tuple. + /// The value of the fourth component of the tuple. + /// The value of the fifth component of the tuple. + /// A 5-tuple (quintuple) whose value is (item1, item2, item3, item4, item5). + public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) => + new ValueTuple(item1, item2, item3, item4, item5); + + /// Creates a new struct 6-tuple, or sextuple. + /// The type of the first component of the tuple. + /// The type of the second component of the tuple. + /// The type of the third component of the tuple. + /// The type of the fourth component of the tuple. + /// The type of the fifth component of the tuple. + /// The type of the sixth component of the tuple. + /// The value of the first component of the tuple. + /// The value of the second component of the tuple. + /// The value of the third component of the tuple. + /// The value of the fourth component of the tuple. + /// The value of the fifth component of the tuple. + /// The value of the sixth component of the tuple. + /// A 6-tuple (sextuple) whose value is (item1, item2, item3, item4, item5, item6). + public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) => + new ValueTuple(item1, item2, item3, item4, item5, item6); + + /// Creates a new struct 7-tuple, or septuple. + /// The type of the first component of the tuple. + /// The type of the second component of the tuple. + /// The type of the third component of the tuple. + /// The type of the fourth component of the tuple. + /// The type of the fifth component of the tuple. + /// The type of the sixth component of the tuple. + /// The type of the seventh component of the tuple. + /// The value of the first component of the tuple. + /// The value of the second component of the tuple. + /// The value of the third component of the tuple. + /// The value of the fourth component of the tuple. + /// The value of the fifth component of the tuple. + /// The value of the sixth component of the tuple. + /// The value of the seventh component of the tuple. + /// A 7-tuple (septuple) whose value is (item1, item2, item3, item4, item5, item6, item7). + public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) => + new ValueTuple(item1, item2, item3, item4, item5, item6, item7); + + /// Creates a new struct 8-tuple, or octuple. + /// The type of the first component of the tuple. + /// The type of the second component of the tuple. + /// The type of the third component of the tuple. + /// The type of the fourth component of the tuple. + /// The type of the fifth component of the tuple. + /// The type of the sixth component of the tuple. + /// The type of the seventh component of the tuple. + /// The type of the eighth component of the tuple. + /// The value of the first component of the tuple. + /// The value of the second component of the tuple. + /// The value of the third component of the tuple. + /// The value of the fourth component of the tuple. + /// The value of the fifth component of the tuple. + /// The value of the sixth component of the tuple. + /// The value of the seventh component of the tuple. + /// The value of the eighth component of the tuple. + /// An 8-tuple (octuple) whose value is (item1, item2, item3, item4, item5, item6, item7, item8). + public static ValueTuple> Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8) => + new ValueTuple>(item1, item2, item3, item4, item5, item6, item7, ValueTuple.Create(item8)); + + internal static int CombineHashCodes(int h1, int h2) + { + return HashHelpers.Combine(HashHelpers.Combine(HashHelpers.RandomSeed, h1), h2); + } + + internal static int CombineHashCodes(int h1, int h2, int h3) + { + return HashHelpers.Combine(CombineHashCodes(h1, h2), h3); + } + + internal static int CombineHashCodes(int h1, int h2, int h3, int h4) + { + return HashHelpers.Combine(CombineHashCodes(h1, h2, h3), h4); + } + + internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5) + { + return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4), h5); + } + + internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6) + { + return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5), h6); + } + + internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7) + { + return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5, h6), h7); + } + + internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8) + { + return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5, h6, h7), h8); + } + } + + /// Represents a 1-tuple, or singleton, as a value type. + /// The type of the tuple's only component. + [Serializable] + public struct ValueTuple + : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple + { + /// + /// The current instance's first component. + /// + public T1 Item1; + + /// + /// Initializes a new instance of the value type. + /// + /// The value of the tuple's first component. + public ValueTuple(T1 item1) + { + Item1 = item1; + } + + /// + /// Returns a value that indicates whether the current instance is equal to a specified object. + /// + /// The object to compare with this instance. + /// if the current instance is equal to the specified object; otherwise, . + /// + /// The parameter is considered to be equal to the current instance under the following conditions: + /// + /// It is a value type. + /// Its components are of the same types as those of the current instance. + /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. + /// + /// + public override bool Equals(object obj) + { + return obj is ValueTuple && Equals((ValueTuple)obj); + } + + /// + /// Returns a value that indicates whether the current + /// instance is equal to a specified . + /// + /// The tuple to compare with this instance. + /// if the current instance is equal to the specified tuple; otherwise, . + /// + /// The parameter is considered to be equal to the current instance if each of its field + /// is equal to that of the current instance, using the default comparer for that field's type. + /// + public bool Equals(ValueTuple other) + { + return EqualityComparer.Default.Equals(Item1, other.Item1); + } + + bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) + { + if (other == null || !(other is ValueTuple)) return false; + + var objTuple = (ValueTuple)other; + + return comparer.Equals(Item1, objTuple.Item1); + } + + int IComparable.CompareTo(object other) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException(); + } + + var objTuple = (ValueTuple)other; + + return Comparer.Default.Compare(Item1, objTuple.Item1); + } + + /// Compares this instance to a specified instance and returns an indication of their relative values. + /// An instance to compare. + /// + /// A signed number indicating the relative values of this instance and . + /// Returns less than zero if this instance is less than , zero if this + /// instance is equal to , and greater than zero if this instance is greater + /// than . + /// + public int CompareTo(ValueTuple other) + { + return Comparer.Default.Compare(Item1, other.Item1); + } + + int IStructuralComparable.CompareTo(object other, IComparer comparer) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException(); + } + + var objTuple = (ValueTuple)other; + + return comparer.Compare(Item1, objTuple.Item1); + } + + /// + /// Returns the hash code for the current instance. + /// + /// A 32-bit signed integer hash code. + public override int GetHashCode() + { + return Item1?.GetHashCode() ?? 0; + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) + { + return comparer.GetHashCode(Item1); + } + + int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) + { + return comparer.GetHashCode(Item1); + } + + /// + /// Returns a string that represents the value of this instance. + /// + /// The string representation of this instance. + /// + /// The string returned by this method takes the form (Item1), + /// where Item1 represents the value of . If the field is , + /// it is represented as . + /// + public override string ToString() + { + return "(" + Item1?.ToString() + ")"; + } + + string IValueTupleInternal.ToStringEnd() + { + return Item1?.ToString() + ")"; + } + + /// + /// The number of positions in this data structure. + /// + int ITuple.Length => 1; + + /// + /// Get the element at position . + /// + object ITuple.this[int index] + { + get + { + if (index != 0) + { + throw new IndexOutOfRangeException(); + } + return Item1; + } + } + } + + /// + /// Represents a 2-tuple, or pair, as a value type. + /// + /// The type of the tuple's first component. + /// The type of the tuple's second component. + [Serializable] + [StructLayout(LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple + { + /// + /// The current instance's first component. + /// + public T1 Item1; + + /// + /// The current instance's first component. + /// + public T2 Item2; + + /// + /// Initializes a new instance of the value type. + /// + /// The value of the tuple's first component. + /// The value of the tuple's second component. + public ValueTuple(T1 item1, T2 item2) + { + Item1 = item1; + Item2 = item2; + } + + /// + /// Returns a value that indicates whether the current instance is equal to a specified object. + /// + /// The object to compare with this instance. + /// if the current instance is equal to the specified object; otherwise, . + /// + /// + /// The parameter is considered to be equal to the current instance under the following conditions: + /// + /// It is a value type. + /// Its components are of the same types as those of the current instance. + /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. + /// + /// + public override bool Equals(object obj) + { + return obj is ValueTuple && Equals((ValueTuple)obj); + } + + /// + /// Returns a value that indicates whether the current instance is equal to a specified . + /// + /// The tuple to compare with this instance. + /// if the current instance is equal to the specified tuple; otherwise, . + /// + /// The parameter is considered to be equal to the current instance if each of its fields + /// are equal to that of the current instance, using the default comparer for that field's type. + /// + public bool Equals(ValueTuple other) + { + return EqualityComparer.Default.Equals(Item1, other.Item1) + && EqualityComparer.Default.Equals(Item2, other.Item2); + } + + /// + /// Returns a value that indicates whether the current instance is equal to a specified object based on a specified comparison method. + /// + /// The object to compare with this instance. + /// An object that defines the method to use to evaluate whether the two objects are equal. + /// if the current instance is equal to the specified object; otherwise, . + /// + /// + /// This member is an explicit interface member implementation. It can be used only when the + /// instance is cast to an interface. + /// + /// The implementation is called only if other is not , + /// and if it can be successfully cast (in C#) or converted (in Visual Basic) to a + /// whose components are of the same types as those of the current instance. The IStructuralEquatable.Equals(Object, IEqualityComparer) method + /// first passes the values of the objects to be compared to the + /// implementation. If this method call returns , the method is + /// called again and passed the values of the two instances. + /// + bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) + { + if (other == null || !(other is ValueTuple)) return false; + + var objTuple = (ValueTuple)other; + + return comparer.Equals(Item1, objTuple.Item1) + && comparer.Equals(Item2, objTuple.Item2); + } + + int IComparable.CompareTo(object other) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException(); + } + + return CompareTo((ValueTuple)other); + } + + /// Compares this instance to a specified instance and returns an indication of their relative values. + /// An instance to compare. + /// + /// A signed number indicating the relative values of this instance and . + /// Returns less than zero if this instance is less than , zero if this + /// instance is equal to , and greater than zero if this instance is greater + /// than . + /// + public int CompareTo(ValueTuple other) + { + int c = Comparer.Default.Compare(Item1, other.Item1); + if (c != 0) return c; + + return Comparer.Default.Compare(Item2, other.Item2); + } + + int IStructuralComparable.CompareTo(object other, IComparer comparer) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException(); + } + + var objTuple = (ValueTuple)other; + + int c = comparer.Compare(Item1, objTuple.Item1); + if (c != 0) return c; + + return comparer.Compare(Item2, objTuple.Item2); + } + + /// + /// Returns the hash code for the current instance. + /// + /// A 32-bit signed integer hash code. + public override int GetHashCode() + { + return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0, + Item2?.GetHashCode() ?? 0); + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) + { + return GetHashCodeCore(comparer); + } + + private int GetHashCodeCore(IEqualityComparer comparer) + { + return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), + comparer.GetHashCode(Item2)); + } + + int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) + { + return GetHashCodeCore(comparer); + } + + /// + /// Returns a string that represents the value of this instance. + /// + /// The string representation of this instance. + /// + /// The string returned by this method takes the form (Item1, Item2), + /// where Item1 and Item2 represent the values of the + /// and fields. If either field value is , + /// it is represented as . + /// + public override string ToString() + { + return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ")"; + } + + string IValueTupleInternal.ToStringEnd() + { + return Item1?.ToString() + ", " + Item2?.ToString() + ")"; + } + + /// + /// The number of positions in this data structure. + /// + int ITuple.Length => 2; + + /// + /// Get the element at position . + /// + object ITuple.this[int index] + { + get + { + switch (index) + { + case 0: + return Item1; + case 1: + return Item2; + default: + throw new IndexOutOfRangeException(); + } + } + } + } + + /// + /// Represents a 3-tuple, or triple, as a value type. + /// + /// The type of the tuple's first component. + /// The type of the tuple's second component. + /// The type of the tuple's third component. + [Serializable] + [StructLayout(LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple + { + /// + /// The current instance's first component. + /// + public T1 Item1; + /// + /// The current instance's second component. + /// + public T2 Item2; + /// + /// The current instance's third component. + /// + public T3 Item3; + + /// + /// Initializes a new instance of the value type. + /// + /// The value of the tuple's first component. + /// The value of the tuple's second component. + /// The value of the tuple's third component. + public ValueTuple(T1 item1, T2 item2, T3 item3) + { + Item1 = item1; + Item2 = item2; + Item3 = item3; + } + + /// + /// Returns a value that indicates whether the current instance is equal to a specified object. + /// + /// The object to compare with this instance. + /// if the current instance is equal to the specified object; otherwise, . + /// + /// The parameter is considered to be equal to the current instance under the following conditions: + /// + /// It is a value type. + /// Its components are of the same types as those of the current instance. + /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. + /// + /// + public override bool Equals(object obj) + { + return obj is ValueTuple && Equals((ValueTuple)obj); + } + + /// + /// Returns a value that indicates whether the current + /// instance is equal to a specified . + /// + /// The tuple to compare with this instance. + /// if the current instance is equal to the specified tuple; otherwise, . + /// + /// The parameter is considered to be equal to the current instance if each of its fields + /// are equal to that of the current instance, using the default comparer for that field's type. + /// + public bool Equals(ValueTuple other) + { + return EqualityComparer.Default.Equals(Item1, other.Item1) + && EqualityComparer.Default.Equals(Item2, other.Item2) + && EqualityComparer.Default.Equals(Item3, other.Item3); + } + + bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) + { + if (other == null || !(other is ValueTuple)) return false; + + var objTuple = (ValueTuple)other; + + return comparer.Equals(Item1, objTuple.Item1) + && comparer.Equals(Item2, objTuple.Item2) + && comparer.Equals(Item3, objTuple.Item3); + } + + int IComparable.CompareTo(object other) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException(); + } + + return CompareTo((ValueTuple)other); + } + + /// Compares this instance to a specified instance and returns an indication of their relative values. + /// An instance to compare. + /// + /// A signed number indicating the relative values of this instance and . + /// Returns less than zero if this instance is less than , zero if this + /// instance is equal to , and greater than zero if this instance is greater + /// than . + /// + public int CompareTo(ValueTuple other) + { + int c = Comparer.Default.Compare(Item1, other.Item1); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item2, other.Item2); + if (c != 0) return c; + + return Comparer.Default.Compare(Item3, other.Item3); + } + + int IStructuralComparable.CompareTo(object other, IComparer comparer) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException(); + } + + var objTuple = (ValueTuple)other; + + int c = comparer.Compare(Item1, objTuple.Item1); + if (c != 0) return c; + + c = comparer.Compare(Item2, objTuple.Item2); + if (c != 0) return c; + + return comparer.Compare(Item3, objTuple.Item3); + } + + /// + /// Returns the hash code for the current instance. + /// + /// A 32-bit signed integer hash code. + public override int GetHashCode() + { + return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0, + Item2?.GetHashCode() ?? 0, + Item3?.GetHashCode() ?? 0); + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) + { + return GetHashCodeCore(comparer); + } + + private int GetHashCodeCore(IEqualityComparer comparer) + { + return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), + comparer.GetHashCode(Item2), + comparer.GetHashCode(Item3)); + } + + int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) + { + return GetHashCodeCore(comparer); + } + + /// + /// Returns a string that represents the value of this instance. + /// + /// The string representation of this instance. + /// + /// The string returned by this method takes the form (Item1, Item2, Item3). + /// If any field value is , it is represented as . + /// + public override string ToString() + { + return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ")"; + } + + string IValueTupleInternal.ToStringEnd() + { + return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ")"; + } + + /// + /// The number of positions in this data structure. + /// + int ITuple.Length => 3; + + /// + /// Get the element at position . + /// + object ITuple.this[int index] + { + get + { + switch (index) + { + case 0: + return Item1; + case 1: + return Item2; + case 2: + return Item3; + default: + throw new IndexOutOfRangeException(); + } + } + } + } + + /// + /// Represents a 4-tuple, or quadruple, as a value type. + /// + /// The type of the tuple's first component. + /// The type of the tuple's second component. + /// The type of the tuple's third component. + /// The type of the tuple's fourth component. + [Serializable] + [StructLayout(LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple + { + /// + /// The current instance's first component. + /// + public T1 Item1; + /// + /// The current instance's second component. + /// + public T2 Item2; + /// + /// The current instance's third component. + /// + public T3 Item3; + /// + /// The current instance's fourth component. + /// + public T4 Item4; + + /// + /// Initializes a new instance of the value type. + /// + /// The value of the tuple's first component. + /// The value of the tuple's second component. + /// The value of the tuple's third component. + /// The value of the tuple's fourth component. + public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4) + { + Item1 = item1; + Item2 = item2; + Item3 = item3; + Item4 = item4; + } + + /// + /// Returns a value that indicates whether the current instance is equal to a specified object. + /// + /// The object to compare with this instance. + /// if the current instance is equal to the specified object; otherwise, . + /// + /// The parameter is considered to be equal to the current instance under the following conditions: + /// + /// It is a value type. + /// Its components are of the same types as those of the current instance. + /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. + /// + /// + public override bool Equals(object obj) + { + return obj is ValueTuple && Equals((ValueTuple)obj); + } + + /// + /// Returns a value that indicates whether the current + /// instance is equal to a specified . + /// + /// The tuple to compare with this instance. + /// if the current instance is equal to the specified tuple; otherwise, . + /// + /// The parameter is considered to be equal to the current instance if each of its fields + /// are equal to that of the current instance, using the default comparer for that field's type. + /// + public bool Equals(ValueTuple other) + { + return EqualityComparer.Default.Equals(Item1, other.Item1) + && EqualityComparer.Default.Equals(Item2, other.Item2) + && EqualityComparer.Default.Equals(Item3, other.Item3) + && EqualityComparer.Default.Equals(Item4, other.Item4); + } + + bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) + { + if (other == null || !(other is ValueTuple)) return false; + + var objTuple = (ValueTuple)other; + + return comparer.Equals(Item1, objTuple.Item1) + && comparer.Equals(Item2, objTuple.Item2) + && comparer.Equals(Item3, objTuple.Item3) + && comparer.Equals(Item4, objTuple.Item4); + } + + int IComparable.CompareTo(object other) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException(); + } + + return CompareTo((ValueTuple)other); + } + + /// Compares this instance to a specified instance and returns an indication of their relative values. + /// An instance to compare. + /// + /// A signed number indicating the relative values of this instance and . + /// Returns less than zero if this instance is less than , zero if this + /// instance is equal to , and greater than zero if this instance is greater + /// than . + /// + public int CompareTo(ValueTuple other) + { + int c = Comparer.Default.Compare(Item1, other.Item1); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item2, other.Item2); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item3, other.Item3); + if (c != 0) return c; + + return Comparer.Default.Compare(Item4, other.Item4); + } + + int IStructuralComparable.CompareTo(object other, IComparer comparer) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException(); + } + + var objTuple = (ValueTuple)other; + + int c = comparer.Compare(Item1, objTuple.Item1); + if (c != 0) return c; + + c = comparer.Compare(Item2, objTuple.Item2); + if (c != 0) return c; + + c = comparer.Compare(Item3, objTuple.Item3); + if (c != 0) return c; + + return comparer.Compare(Item4, objTuple.Item4); + } + + /// + /// Returns the hash code for the current instance. + /// + /// A 32-bit signed integer hash code. + public override int GetHashCode() + { + return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0, + Item2?.GetHashCode() ?? 0, + Item3?.GetHashCode() ?? 0, + Item4?.GetHashCode() ?? 0); + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) + { + return GetHashCodeCore(comparer); + } + + private int GetHashCodeCore(IEqualityComparer comparer) + { + return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), + comparer.GetHashCode(Item2), + comparer.GetHashCode(Item3), + comparer.GetHashCode(Item4)); + } + + int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) + { + return GetHashCodeCore(comparer); + } + + /// + /// Returns a string that represents the value of this instance. + /// + /// The string representation of this instance. + /// + /// The string returned by this method takes the form (Item1, Item2, Item3, Item4). + /// If any field value is , it is represented as . + /// + public override string ToString() + { + return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ")"; + } + + string IValueTupleInternal.ToStringEnd() + { + return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ")"; + } + + /// + /// The number of positions in this data structure. + /// + int ITuple.Length => 4; + + /// + /// Get the element at position . + /// + object ITuple.this[int index] + { + get + { + switch (index) + { + case 0: + return Item1; + case 1: + return Item2; + case 2: + return Item3; + case 3: + return Item4; + default: + throw new IndexOutOfRangeException(); + } + } + } + } + + /// + /// Represents a 5-tuple, or quintuple, as a value type. + /// + /// The type of the tuple's first component. + /// The type of the tuple's second component. + /// The type of the tuple's third component. + /// The type of the tuple's fourth component. + /// The type of the tuple's fifth component. + [Serializable] + [StructLayout(LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple + { + /// + /// The current instance's first component. + /// + public T1 Item1; + /// + /// The current instance's second component. + /// + public T2 Item2; + /// + /// The current instance's third component. + /// + public T3 Item3; + /// + /// The current instance's fourth component. + /// + public T4 Item4; + /// + /// The current instance's fifth component. + /// + public T5 Item5; + + /// + /// Initializes a new instance of the value type. + /// + /// The value of the tuple's first component. + /// The value of the tuple's second component. + /// The value of the tuple's third component. + /// The value of the tuple's fourth component. + /// The value of the tuple's fifth component. + public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) + { + Item1 = item1; + Item2 = item2; + Item3 = item3; + Item4 = item4; + Item5 = item5; + } + + /// + /// Returns a value that indicates whether the current instance is equal to a specified object. + /// + /// The object to compare with this instance. + /// if the current instance is equal to the specified object; otherwise, . + /// + /// The parameter is considered to be equal to the current instance under the following conditions: + /// + /// It is a value type. + /// Its components are of the same types as those of the current instance. + /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. + /// + /// + public override bool Equals(object obj) + { + return obj is ValueTuple && Equals((ValueTuple)obj); + } + + /// + /// Returns a value that indicates whether the current + /// instance is equal to a specified . + /// + /// The tuple to compare with this instance. + /// if the current instance is equal to the specified tuple; otherwise, . + /// + /// The parameter is considered to be equal to the current instance if each of its fields + /// are equal to that of the current instance, using the default comparer for that field's type. + /// + public bool Equals(ValueTuple other) + { + return EqualityComparer.Default.Equals(Item1, other.Item1) + && EqualityComparer.Default.Equals(Item2, other.Item2) + && EqualityComparer.Default.Equals(Item3, other.Item3) + && EqualityComparer.Default.Equals(Item4, other.Item4) + && EqualityComparer.Default.Equals(Item5, other.Item5); + } + + bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) + { + if (other == null || !(other is ValueTuple)) return false; + + var objTuple = (ValueTuple)other; + + return comparer.Equals(Item1, objTuple.Item1) + && comparer.Equals(Item2, objTuple.Item2) + && comparer.Equals(Item3, objTuple.Item3) + && comparer.Equals(Item4, objTuple.Item4) + && comparer.Equals(Item5, objTuple.Item5); + } + + int IComparable.CompareTo(object other) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException(); + } + + return CompareTo((ValueTuple)other); + } + + /// Compares this instance to a specified instance and returns an indication of their relative values. + /// An instance to compare. + /// + /// A signed number indicating the relative values of this instance and . + /// Returns less than zero if this instance is less than , zero if this + /// instance is equal to , and greater than zero if this instance is greater + /// than . + /// + public int CompareTo(ValueTuple other) + { + int c = Comparer.Default.Compare(Item1, other.Item1); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item2, other.Item2); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item3, other.Item3); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item4, other.Item4); + if (c != 0) return c; + + return Comparer.Default.Compare(Item5, other.Item5); + } + + int IStructuralComparable.CompareTo(object other, IComparer comparer) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException(); + } + + var objTuple = (ValueTuple)other; + + int c = comparer.Compare(Item1, objTuple.Item1); + if (c != 0) return c; + + c = comparer.Compare(Item2, objTuple.Item2); + if (c != 0) return c; + + c = comparer.Compare(Item3, objTuple.Item3); + if (c != 0) return c; + + c = comparer.Compare(Item4, objTuple.Item4); + if (c != 0) return c; + + return comparer.Compare(Item5, objTuple.Item5); + } + + /// + /// Returns the hash code for the current instance. + /// + /// A 32-bit signed integer hash code. + public override int GetHashCode() + { + return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0, + Item2?.GetHashCode() ?? 0, + Item3?.GetHashCode() ?? 0, + Item4?.GetHashCode() ?? 0, + Item5?.GetHashCode() ?? 0); + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) + { + return GetHashCodeCore(comparer); + } + + private int GetHashCodeCore(IEqualityComparer comparer) + { + return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), + comparer.GetHashCode(Item2), + comparer.GetHashCode(Item3), + comparer.GetHashCode(Item4), + comparer.GetHashCode(Item5)); + } + + int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) + { + return GetHashCodeCore(comparer); + } + + /// + /// Returns a string that represents the value of this instance. + /// + /// The string representation of this instance. + /// + /// The string returned by this method takes the form (Item1, Item2, Item3, Item4, Item5). + /// If any field value is , it is represented as . + /// + public override string ToString() + { + return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ")"; + } + + string IValueTupleInternal.ToStringEnd() + { + return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ")"; + } + + /// + /// The number of positions in this data structure. + /// + int ITuple.Length => 5; + + /// + /// Get the element at position . + /// + object ITuple.this[int index] + { + get + { + switch (index) + { + case 0: + return Item1; + case 1: + return Item2; + case 2: + return Item3; + case 3: + return Item4; + case 4: + return Item5; + default: + throw new IndexOutOfRangeException(); + } + } + } + } + + /// + /// Represents a 6-tuple, or sixtuple, as a value type. + /// + /// The type of the tuple's first component. + /// The type of the tuple's second component. + /// The type of the tuple's third component. + /// The type of the tuple's fourth component. + /// The type of the tuple's fifth component. + /// The type of the tuple's sixth component. + [Serializable] + [StructLayout(LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple + { + /// + /// The current instance's first component. + /// + public T1 Item1; + /// + /// The current instance's second component. + /// + public T2 Item2; + /// + /// The current instance's third component. + /// + public T3 Item3; + /// + /// The current instance's fourth component. + /// + public T4 Item4; + /// + /// The current instance's fifth component. + /// + public T5 Item5; + /// + /// The current instance's sixth component. + /// + public T6 Item6; + + /// + /// Initializes a new instance of the value type. + /// + /// The value of the tuple's first component. + /// The value of the tuple's second component. + /// The value of the tuple's third component. + /// The value of the tuple's fourth component. + /// The value of the tuple's fifth component. + /// The value of the tuple's sixth component. + public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) + { + Item1 = item1; + Item2 = item2; + Item3 = item3; + Item4 = item4; + Item5 = item5; + Item6 = item6; + } + + /// + /// Returns a value that indicates whether the current instance is equal to a specified object. + /// + /// The object to compare with this instance. + /// if the current instance is equal to the specified object; otherwise, . + /// + /// The parameter is considered to be equal to the current instance under the following conditions: + /// + /// It is a value type. + /// Its components are of the same types as those of the current instance. + /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. + /// + /// + public override bool Equals(object obj) + { + return obj is ValueTuple && Equals((ValueTuple)obj); + } + + /// + /// Returns a value that indicates whether the current + /// instance is equal to a specified . + /// + /// The tuple to compare with this instance. + /// if the current instance is equal to the specified tuple; otherwise, . + /// + /// The parameter is considered to be equal to the current instance if each of its fields + /// are equal to that of the current instance, using the default comparer for that field's type. + /// + public bool Equals(ValueTuple other) + { + return EqualityComparer.Default.Equals(Item1, other.Item1) + && EqualityComparer.Default.Equals(Item2, other.Item2) + && EqualityComparer.Default.Equals(Item3, other.Item3) + && EqualityComparer.Default.Equals(Item4, other.Item4) + && EqualityComparer.Default.Equals(Item5, other.Item5) + && EqualityComparer.Default.Equals(Item6, other.Item6); + } + + bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) + { + if (other == null || !(other is ValueTuple)) return false; + + var objTuple = (ValueTuple)other; + + return comparer.Equals(Item1, objTuple.Item1) + && comparer.Equals(Item2, objTuple.Item2) + && comparer.Equals(Item3, objTuple.Item3) + && comparer.Equals(Item4, objTuple.Item4) + && comparer.Equals(Item5, objTuple.Item5) + && comparer.Equals(Item6, objTuple.Item6); + } + + int IComparable.CompareTo(object other) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException(); + } + + return CompareTo((ValueTuple)other); + } + + /// Compares this instance to a specified instance and returns an indication of their relative values. + /// An instance to compare. + /// + /// A signed number indicating the relative values of this instance and . + /// Returns less than zero if this instance is less than , zero if this + /// instance is equal to , and greater than zero if this instance is greater + /// than . + /// + public int CompareTo(ValueTuple other) + { + int c = Comparer.Default.Compare(Item1, other.Item1); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item2, other.Item2); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item3, other.Item3); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item4, other.Item4); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item5, other.Item5); + if (c != 0) return c; + + return Comparer.Default.Compare(Item6, other.Item6); + } + + int IStructuralComparable.CompareTo(object other, IComparer comparer) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException(); + } + + var objTuple = (ValueTuple)other; + + int c = comparer.Compare(Item1, objTuple.Item1); + if (c != 0) return c; + + c = comparer.Compare(Item2, objTuple.Item2); + if (c != 0) return c; + + c = comparer.Compare(Item3, objTuple.Item3); + if (c != 0) return c; + + c = comparer.Compare(Item4, objTuple.Item4); + if (c != 0) return c; + + c = comparer.Compare(Item5, objTuple.Item5); + if (c != 0) return c; + + return comparer.Compare(Item6, objTuple.Item6); + } + + /// + /// Returns the hash code for the current instance. + /// + /// A 32-bit signed integer hash code. + public override int GetHashCode() + { + return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0, + Item2?.GetHashCode() ?? 0, + Item3?.GetHashCode() ?? 0, + Item4?.GetHashCode() ?? 0, + Item5?.GetHashCode() ?? 0, + Item6?.GetHashCode() ?? 0); + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) + { + return GetHashCodeCore(comparer); + } + + private int GetHashCodeCore(IEqualityComparer comparer) + { + return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), + comparer.GetHashCode(Item2), + comparer.GetHashCode(Item3), + comparer.GetHashCode(Item4), + comparer.GetHashCode(Item5), + comparer.GetHashCode(Item6)); + } + + int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) + { + return GetHashCodeCore(comparer); + } + + /// + /// Returns a string that represents the value of this instance. + /// + /// The string representation of this instance. + /// + /// The string returned by this method takes the form (Item1, Item2, Item3, Item4, Item5, Item6). + /// If any field value is , it is represented as . + /// + public override string ToString() + { + return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ")"; + } + + string IValueTupleInternal.ToStringEnd() + { + return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ")"; + } + + /// + /// The number of positions in this data structure. + /// + int ITuple.Length => 6; + + /// + /// Get the element at position . + /// + object ITuple.this[int index] + { + get + { + switch (index) + { + case 0: + return Item1; + case 1: + return Item2; + case 2: + return Item3; + case 3: + return Item4; + case 4: + return Item5; + case 5: + return Item6; + default: + throw new IndexOutOfRangeException(); + } + } + } + } + + /// + /// Represents a 7-tuple, or sentuple, as a value type. + /// + /// The type of the tuple's first component. + /// The type of the tuple's second component. + /// The type of the tuple's third component. + /// The type of the tuple's fourth component. + /// The type of the tuple's fifth component. + /// The type of the tuple's sixth component. + /// The type of the tuple's seventh component. + [Serializable] + [StructLayout(LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple + { + /// + /// The current instance's first component. + /// + public T1 Item1; + /// + /// The current instance's second component. + /// + public T2 Item2; + /// + /// The current instance's third component. + /// + public T3 Item3; + /// + /// The current instance's fourth component. + /// + public T4 Item4; + /// + /// The current instance's fifth component. + /// + public T5 Item5; + /// + /// The current instance's sixth component. + /// + public T6 Item6; + /// + /// The current instance's seventh component. + /// + public T7 Item7; + + /// + /// Initializes a new instance of the value type. + /// + /// The value of the tuple's first component. + /// The value of the tuple's second component. + /// The value of the tuple's third component. + /// The value of the tuple's fourth component. + /// The value of the tuple's fifth component. + /// The value of the tuple's sixth component. + /// The value of the tuple's seventh component. + public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) + { + Item1 = item1; + Item2 = item2; + Item3 = item3; + Item4 = item4; + Item5 = item5; + Item6 = item6; + Item7 = item7; + } + + /// + /// Returns a value that indicates whether the current instance is equal to a specified object. + /// + /// The object to compare with this instance. + /// if the current instance is equal to the specified object; otherwise, . + /// + /// The parameter is considered to be equal to the current instance under the following conditions: + /// + /// It is a value type. + /// Its components are of the same types as those of the current instance. + /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. + /// + /// + public override bool Equals(object obj) + { + return obj is ValueTuple && Equals((ValueTuple)obj); + } + + /// + /// Returns a value that indicates whether the current + /// instance is equal to a specified . + /// + /// The tuple to compare with this instance. + /// if the current instance is equal to the specified tuple; otherwise, . + /// + /// The parameter is considered to be equal to the current instance if each of its fields + /// are equal to that of the current instance, using the default comparer for that field's type. + /// + public bool Equals(ValueTuple other) + { + return EqualityComparer.Default.Equals(Item1, other.Item1) + && EqualityComparer.Default.Equals(Item2, other.Item2) + && EqualityComparer.Default.Equals(Item3, other.Item3) + && EqualityComparer.Default.Equals(Item4, other.Item4) + && EqualityComparer.Default.Equals(Item5, other.Item5) + && EqualityComparer.Default.Equals(Item6, other.Item6) + && EqualityComparer.Default.Equals(Item7, other.Item7); + } + + bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) + { + if (other == null || !(other is ValueTuple)) return false; + + var objTuple = (ValueTuple)other; + + return comparer.Equals(Item1, objTuple.Item1) + && comparer.Equals(Item2, objTuple.Item2) + && comparer.Equals(Item3, objTuple.Item3) + && comparer.Equals(Item4, objTuple.Item4) + && comparer.Equals(Item5, objTuple.Item5) + && comparer.Equals(Item6, objTuple.Item6) + && comparer.Equals(Item7, objTuple.Item7); + } + + int IComparable.CompareTo(object other) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException(); + } + + return CompareTo((ValueTuple)other); + } + + /// Compares this instance to a specified instance and returns an indication of their relative values. + /// An instance to compare. + /// + /// A signed number indicating the relative values of this instance and . + /// Returns less than zero if this instance is less than , zero if this + /// instance is equal to , and greater than zero if this instance is greater + /// than . + /// + public int CompareTo(ValueTuple other) + { + int c = Comparer.Default.Compare(Item1, other.Item1); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item2, other.Item2); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item3, other.Item3); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item4, other.Item4); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item5, other.Item5); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item6, other.Item6); + if (c != 0) return c; + + return Comparer.Default.Compare(Item7, other.Item7); + } + + int IStructuralComparable.CompareTo(object other, IComparer comparer) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException(); + } + + var objTuple = (ValueTuple)other; + + int c = comparer.Compare(Item1, objTuple.Item1); + if (c != 0) return c; + + c = comparer.Compare(Item2, objTuple.Item2); + if (c != 0) return c; + + c = comparer.Compare(Item3, objTuple.Item3); + if (c != 0) return c; + + c = comparer.Compare(Item4, objTuple.Item4); + if (c != 0) return c; + + c = comparer.Compare(Item5, objTuple.Item5); + if (c != 0) return c; + + c = comparer.Compare(Item6, objTuple.Item6); + if (c != 0) return c; + + return comparer.Compare(Item7, objTuple.Item7); + } + + /// + /// Returns the hash code for the current instance. + /// + /// A 32-bit signed integer hash code. + public override int GetHashCode() + { + return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0, + Item2?.GetHashCode() ?? 0, + Item3?.GetHashCode() ?? 0, + Item4?.GetHashCode() ?? 0, + Item5?.GetHashCode() ?? 0, + Item6?.GetHashCode() ?? 0, + Item7?.GetHashCode() ?? 0); + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) + { + return GetHashCodeCore(comparer); + } + + private int GetHashCodeCore(IEqualityComparer comparer) + { + return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), + comparer.GetHashCode(Item2), + comparer.GetHashCode(Item3), + comparer.GetHashCode(Item4), + comparer.GetHashCode(Item5), + comparer.GetHashCode(Item6), + comparer.GetHashCode(Item7)); + } + + int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) + { + return GetHashCodeCore(comparer); + } + + /// + /// Returns a string that represents the value of this instance. + /// + /// The string representation of this instance. + /// + /// The string returned by this method takes the form (Item1, Item2, Item3, Item4, Item5, Item6, Item7). + /// If any field value is , it is represented as . + /// + public override string ToString() + { + return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ")"; + } + + string IValueTupleInternal.ToStringEnd() + { + return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ")"; + } + + /// + /// The number of positions in this data structure. + /// + int ITuple.Length => 7; + + /// + /// Get the element at position . + /// + object ITuple.this[int index] + { + get + { + switch (index) + { + case 0: + return Item1; + case 1: + return Item2; + case 2: + return Item3; + case 3: + return Item4; + case 4: + return Item5; + case 5: + return Item6; + case 6: + return Item7; + default: + throw new IndexOutOfRangeException(); + } + } + } + } + + /// + /// Represents an 8-tuple, or octuple, as a value type. + /// + /// The type of the tuple's first component. + /// The type of the tuple's second component. + /// The type of the tuple's third component. + /// The type of the tuple's fourth component. + /// The type of the tuple's fifth component. + /// The type of the tuple's sixth component. + /// The type of the tuple's seventh component. + /// The type of the tuple's eighth component. + [Serializable] + [StructLayout(LayoutKind.Auto)] + public struct ValueTuple + : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple + where TRest : struct + { + /// + /// The current instance's first component. + /// + public T1 Item1; + /// + /// The current instance's second component. + /// + public T2 Item2; + /// + /// The current instance's third component. + /// + public T3 Item3; + /// + /// The current instance's fourth component. + /// + public T4 Item4; + /// + /// The current instance's fifth component. + /// + public T5 Item5; + /// + /// The current instance's sixth component. + /// + public T6 Item6; + /// + /// The current instance's seventh component. + /// + public T7 Item7; + /// + /// The current instance's eighth component. + /// + public TRest Rest; + + /// + /// Initializes a new instance of the value type. + /// + /// The value of the tuple's first component. + /// The value of the tuple's second component. + /// The value of the tuple's third component. + /// The value of the tuple's fourth component. + /// The value of the tuple's fifth component. + /// The value of the tuple's sixth component. + /// The value of the tuple's seventh component. + /// The value of the tuple's eight component. + public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) + { + if (!(rest is IValueTupleInternal)) + { + throw new ArgumentException(); + } + + Item1 = item1; + Item2 = item2; + Item3 = item3; + Item4 = item4; + Item5 = item5; + Item6 = item6; + Item7 = item7; + Rest = rest; + } + + /// + /// Returns a value that indicates whether the current instance is equal to a specified object. + /// + /// The object to compare with this instance. + /// if the current instance is equal to the specified object; otherwise, . + /// + /// The parameter is considered to be equal to the current instance under the following conditions: + /// + /// It is a value type. + /// Its components are of the same types as those of the current instance. + /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. + /// + /// + public override bool Equals(object obj) + { + return obj is ValueTuple && Equals((ValueTuple)obj); + } + + /// + /// Returns a value that indicates whether the current + /// instance is equal to a specified . + /// + /// The tuple to compare with this instance. + /// if the current instance is equal to the specified tuple; otherwise, . + /// + /// The parameter is considered to be equal to the current instance if each of its fields + /// are equal to that of the current instance, using the default comparer for that field's type. + /// + public bool Equals(ValueTuple other) + { + return EqualityComparer.Default.Equals(Item1, other.Item1) + && EqualityComparer.Default.Equals(Item2, other.Item2) + && EqualityComparer.Default.Equals(Item3, other.Item3) + && EqualityComparer.Default.Equals(Item4, other.Item4) + && EqualityComparer.Default.Equals(Item5, other.Item5) + && EqualityComparer.Default.Equals(Item6, other.Item6) + && EqualityComparer.Default.Equals(Item7, other.Item7) + && EqualityComparer.Default.Equals(Rest, other.Rest); + } + + bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) + { + if (other == null || !(other is ValueTuple)) return false; + + var objTuple = (ValueTuple)other; + + return comparer.Equals(Item1, objTuple.Item1) + && comparer.Equals(Item2, objTuple.Item2) + && comparer.Equals(Item3, objTuple.Item3) + && comparer.Equals(Item4, objTuple.Item4) + && comparer.Equals(Item5, objTuple.Item5) + && comparer.Equals(Item6, objTuple.Item6) + && comparer.Equals(Item7, objTuple.Item7) + && comparer.Equals(Rest, objTuple.Rest); + } + + int IComparable.CompareTo(object other) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException(); + } + + return CompareTo((ValueTuple)other); + } + + /// Compares this instance to a specified instance and returns an indication of their relative values. + /// An instance to compare. + /// + /// A signed number indicating the relative values of this instance and . + /// Returns less than zero if this instance is less than , zero if this + /// instance is equal to , and greater than zero if this instance is greater + /// than . + /// + public int CompareTo(ValueTuple other) + { + int c = Comparer.Default.Compare(Item1, other.Item1); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item2, other.Item2); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item3, other.Item3); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item4, other.Item4); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item5, other.Item5); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item6, other.Item6); + if (c != 0) return c; + + c = Comparer.Default.Compare(Item7, other.Item7); + if (c != 0) return c; + + return Comparer.Default.Compare(Rest, other.Rest); + } + + int IStructuralComparable.CompareTo(object other, IComparer comparer) + { + if (other == null) return 1; + + if (!(other is ValueTuple)) + { + throw new ArgumentException(); + } + + var objTuple = (ValueTuple)other; + + int c = comparer.Compare(Item1, objTuple.Item1); + if (c != 0) return c; + + c = comparer.Compare(Item2, objTuple.Item2); + if (c != 0) return c; + + c = comparer.Compare(Item3, objTuple.Item3); + if (c != 0) return c; + + c = comparer.Compare(Item4, objTuple.Item4); + if (c != 0) return c; + + c = comparer.Compare(Item5, objTuple.Item5); + if (c != 0) return c; + + c = comparer.Compare(Item6, objTuple.Item6); + if (c != 0) return c; + + c = comparer.Compare(Item7, objTuple.Item7); + if (c != 0) return c; + + return comparer.Compare(Rest, objTuple.Rest); + } + + /// + /// Returns the hash code for the current instance. + /// + /// A 32-bit signed integer hash code. + public override int GetHashCode() + { + // We want to have a limited hash in this case. We'll use the last 8 elements of the tuple + IValueTupleInternal rest = Rest as IValueTupleInternal; + if (rest == null) + { + return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0, + Item2?.GetHashCode() ?? 0, + Item3?.GetHashCode() ?? 0, + Item4?.GetHashCode() ?? 0, + Item5?.GetHashCode() ?? 0, + Item6?.GetHashCode() ?? 0, + Item7?.GetHashCode() ?? 0); + } + + int size = rest.Length; + if (size >= 8) { return rest.GetHashCode(); } + + // In this case, the rest member has less than 8 elements so we need to combine some our elements with the elements in rest + int k = 8 - size; + switch (k) + { + case 1: + return ValueTuple.CombineHashCodes(Item7?.GetHashCode() ?? 0, + rest.GetHashCode()); + case 2: + return ValueTuple.CombineHashCodes(Item6?.GetHashCode() ?? 0, + Item7?.GetHashCode() ?? 0, + rest.GetHashCode()); + case 3: + return ValueTuple.CombineHashCodes(Item5?.GetHashCode() ?? 0, + Item6?.GetHashCode() ?? 0, + Item7?.GetHashCode() ?? 0, + rest.GetHashCode()); + case 4: + return ValueTuple.CombineHashCodes(Item4?.GetHashCode() ?? 0, + Item5?.GetHashCode() ?? 0, + Item6?.GetHashCode() ?? 0, + Item7?.GetHashCode() ?? 0, + rest.GetHashCode()); + case 5: + return ValueTuple.CombineHashCodes(Item3?.GetHashCode() ?? 0, + Item4?.GetHashCode() ?? 0, + Item5?.GetHashCode() ?? 0, + Item6?.GetHashCode() ?? 0, + Item7?.GetHashCode() ?? 0, + rest.GetHashCode()); + case 6: + return ValueTuple.CombineHashCodes(Item2?.GetHashCode() ?? 0, + Item3?.GetHashCode() ?? 0, + Item4?.GetHashCode() ?? 0, + Item5?.GetHashCode() ?? 0, + Item6?.GetHashCode() ?? 0, + Item7?.GetHashCode() ?? 0, + rest.GetHashCode()); + case 7: + case 8: + return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0, + Item2?.GetHashCode() ?? 0, + Item3?.GetHashCode() ?? 0, + Item4?.GetHashCode() ?? 0, + Item5?.GetHashCode() ?? 0, + Item6?.GetHashCode() ?? 0, + Item7?.GetHashCode() ?? 0, + rest.GetHashCode()); + } + + Contract.Assert(false, "Missed all cases for computing ValueTuple hash code"); + return -1; + } + + int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) + { + return GetHashCodeCore(comparer); + } + + private int GetHashCodeCore(IEqualityComparer comparer) + { + // We want to have a limited hash in this case. We'll use the last 8 elements of the tuple + IValueTupleInternal rest = Rest as IValueTupleInternal; + if (rest == null) + { + return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), + comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), + comparer.GetHashCode(Item7)); + } + + int size = rest.Length; + if (size >= 8) { return rest.GetHashCode(comparer); } + + // In this case, the rest member has less than 8 elements so we need to combine some our elements with the elements in rest + int k = 8 - size; + switch (k) + { + case 1: + return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item7), rest.GetHashCode(comparer)); + case 2: + return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), rest.GetHashCode(comparer)); + case 3: + return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), + rest.GetHashCode(comparer)); + case 4: + return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), + comparer.GetHashCode(Item7), rest.GetHashCode(comparer)); + case 5: + return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), + comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), rest.GetHashCode(comparer)); + case 6: + return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), + comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), + rest.GetHashCode(comparer)); + case 7: + case 8: + return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), + comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), + comparer.GetHashCode(Item7), rest.GetHashCode(comparer)); + } + + Contract.Assert(false, "Missed all cases for computing ValueTuple hash code"); + return -1; + } + + int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) + { + return GetHashCodeCore(comparer); + } + + /// + /// Returns a string that represents the value of this instance. + /// + /// The string representation of this instance. + /// + /// The string returned by this method takes the form (Item1, Item2, Item3, Item4, Item5, Item6, Item7, Rest). + /// If any field value is , it is represented as . + /// + public override string ToString() + { + IValueTupleInternal rest = Rest as IValueTupleInternal; + if (rest == null) + { + return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + Rest.ToString() + ")"; + } + else + { + return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + rest.ToStringEnd(); + } + } + + string IValueTupleInternal.ToStringEnd() + { + IValueTupleInternal rest = Rest as IValueTupleInternal; + if (rest == null) + { + return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + Rest.ToString() + ")"; + } + else + { + return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + rest.ToStringEnd(); + } + } + + /// + /// The number of positions in this data structure. + /// + int ITuple.Length + { + get + { + IValueTupleInternal rest = Rest as IValueTupleInternal; + return rest == null ? 8 : 7 + rest.Length; + } + } + + /// + /// Get the element at position . + /// + object ITuple.this[int index] + { + get + { + switch (index) + { + case 0: + return Item1; + case 1: + return Item2; + case 2: + return Item3; + case 3: + return Item4; + case 4: + return Item5; + case 5: + return Item6; + case 6: + return Item7; + } + + IValueTupleInternal rest = Rest as IValueTupleInternal; + if (rest == null) + { + if (index == 7) + { + return Rest; + } + throw new IndexOutOfRangeException(); + } + return rest[index - 7]; + } + } + } +} +#endif diff --git a/src/dotnetCampus.LatestCSharpFeatures/_._ b/src/dotnetCampus.LatestCSharpFeatures/_._ deleted file mode 100644 index e69de29..0000000 diff --git a/src/dotnetCampus.LatestCSharpFeatures/dotnetCampus.LatestCSharpFeatures.csproj b/src/dotnetCampus.LatestCSharpFeatures/dotnetCampus.LatestCSharpFeatures.csproj index 015acc3..b8d5677 100644 --- a/src/dotnetCampus.LatestCSharpFeatures/dotnetCampus.LatestCSharpFeatures.csproj +++ b/src/dotnetCampus.LatestCSharpFeatures/dotnetCampus.LatestCSharpFeatures.csproj @@ -1,25 +1,16 @@  - net7.0;net5.0;netcoreapp3.0;netstandard2.0;net40 + net8.0;netcoreapp3.0;netstandard2.0;net40 true System.Diagnostics.CodeAnalysis - This comprehensive package provides support for the latest C# language features in your project, enabling older .NET projects to use newer C# language constructs. Currently includes support for 'nullable', 'init', and 'required' keywords. The types introduced are public, allowing these features to propagate to other projects that reference this one. By installing this package, you get all the newest C# features in one place, eliminating the need to install separate packages for each feature. Future updates will include more new features as they are released. - - - + This comprehensive package provides support for the latest C# language features in your project, enabling older .NET projects to use newer C# language constructs. Currently includes support for 'nullable', 'init', and 'required' keywords. The types introduced are internal, confining these features to the project itself without affecting other projects that reference it. By installing this package, you get all the newest C# features in one place, eliminating the need to install separate packages for each feature. Future updates will include more new features as they are released. false - - - - - - - + - + diff --git a/src/dotnetCampus.Nullable.Source/dotnetCampus.Nullable.Source.csproj b/src/dotnetCampus.Nullable.Source/dotnetCampus.Nullable.Source.csproj deleted file mode 100644 index f358221..0000000 --- a/src/dotnetCampus.Nullable.Source/dotnetCampus.Nullable.Source.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - - net5.0;netcoreapp3.0;netstandard2.0;net40 - System.Diagnostics.CodeAnalysis - dotnetCampus.Nullable - If you use C# 8.0 or later and enable the nullable types, this '.Source' library adds internal nullable reference attributes to your project. This confines the new language feature to the project itself without affecting other projects that reference it. - - - - - - - diff --git a/src/dotnetCampus.Nullable/_._ b/src/dotnetCampus.Nullable/_._ deleted file mode 100644 index e69de29..0000000 diff --git a/src/dotnetCampus.Nullable/dotnetCampus.Nullable.csproj b/src/dotnetCampus.Nullable/dotnetCampus.Nullable.csproj deleted file mode 100644 index 13c7890..0000000 --- a/src/dotnetCampus.Nullable/dotnetCampus.Nullable.csproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - net5.0;netcoreapp3.0;netstandard2.0;net40 - true - System.Diagnostics.CodeAnalysis - If you use C# 8.0 or later and enable the nullable types, this library adds public nullable reference attributes to your project, allowing the new language feature to be propagated to other projects that reference this one. - $(DefineConstants);USE_PUBLIC_LATEST_CSHARP_FEATURES - - - - false - - - - - - - - - - - - - diff --git a/src/dotnetCampus.Required.Source/dotnetCampus.Required.Source.csproj b/src/dotnetCampus.Required.Source/dotnetCampus.Required.Source.csproj deleted file mode 100644 index 30e8a6c..0000000 --- a/src/dotnetCampus.Required.Source/dotnetCampus.Required.Source.csproj +++ /dev/null @@ -1,22 +0,0 @@ - - - - net7.0;netcoreapp3.0;netstandard2.0;net40 - System.Diagnostics.CodeAnalysis - dotnetCampus.Required - For C# 11.0 and newer. This package adds support for the 'required' keyword in your project, enforcing that fields or properties are initialized during object initialization. The types introduced are internal, meaning the 'required' functionality is limited to this project and won't propagate to referencing projects. - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/dotnetCampus.Required/_._ b/src/dotnetCampus.Required/_._ deleted file mode 100644 index e69de29..0000000 diff --git a/src/dotnetCampus.Required/dotnetCampus.Required.csproj b/src/dotnetCampus.Required/dotnetCampus.Required.csproj deleted file mode 100644 index f353856..0000000 --- a/src/dotnetCampus.Required/dotnetCampus.Required.csproj +++ /dev/null @@ -1,29 +0,0 @@ - - - - net7.0;net5.0;netcoreapp3.0;netstandard2.0;net40 - true - System.Diagnostics.CodeAnalysis - If you use C# 9.0 or later and want to use record types, this library adds public IsExternalInit attribute support for your project, allowing the new language feature to be propagated to other projects that reference this one. - $(DefineConstants);USE_PUBLIC_LATEST_CSHARP_FEATURES - - - - false - - - - - - - - - - - - - - - - - From a1e66324bfbc683afff83a4476a9fc808c7fe9b8 Mon Sep 17 00:00:00 2001 From: walterlv Date: Sat, 27 Apr 2024 10:47:54 +0800 Subject: [PATCH 03/23] Fix build --- dotnetCampus.LatestCSharpFeatures.sln | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dotnetCampus.LatestCSharpFeatures.sln b/dotnetCampus.LatestCSharpFeatures.sln index 573218d..d2810c4 100644 --- a/dotnetCampus.LatestCSharpFeatures.sln +++ b/dotnetCampus.LatestCSharpFeatures.sln @@ -14,6 +14,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{8A6F61D3 EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnetCampus.LatestCSharpFeatures", "src\dotnetCampus.LatestCSharpFeatures\dotnetCampus.LatestCSharpFeatures.csproj", "{D0B0F7EB-3C81-45C4-BB47-5DCB16F2EA55}" + ProjectSection(ProjectDependencies) = postProject + {642FA0CA-E827-4D96-9358-D596CD87DAF4} = {642FA0CA-E827-4D96-9358-D596CD87DAF4} + EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{878C1D77-0A77-44BD-847E-164188B10677}" EndProject From 6019904f7ef1d5953340761c54460088c3f53ae0 Mon Sep 17 00:00:00 2001 From: walterlv Date: Sat, 27 Apr 2024 10:48:10 +0800 Subject: [PATCH 04/23] Use .NET original xml document of nullable --- .../Nullable/Nullable.cs | 156 ++++++------------ 1 file changed, 55 insertions(+), 101 deletions(-) diff --git a/src/dotnetCampus.LatestCSharpFeatures/Nullable/Nullable.cs b/src/dotnetCampus.LatestCSharpFeatures/Nullable/Nullable.cs index b785da3..5c86fdf 100644 --- a/src/dotnetCampus.LatestCSharpFeatures/Nullable/Nullable.cs +++ b/src/dotnetCampus.LatestCSharpFeatures/Nullable/Nullable.cs @@ -1,215 +1,175 @@ -namespace System.Diagnostics.CodeAnalysis +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Diagnostics.CodeAnalysis { -#if NETCOREAPP3_0 || NETCOREAPP3_1 || NET5_0_OR_GREATER +#if NETSTANDARD2_1 || NETCOREAPP3_0 || NETCOREAPP3_1 || NET5_0_OR_GREATER #else - /// - /// 标记一个不可空的输入实际上是可以传入 null 的。 - /// + /// Specifies that null is allowed as an input even if the corresponding type disallows it. [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] #if USE_PUBLIC_LATEST_CSHARP_FEATURES public #else internal #endif - sealed class AllowNullAttribute : Attribute { } + sealed class AllowNullAttribute : Attribute { } - /// - /// 标记一个可空的输入实际上不应该传入 null。 - /// + /// Specifies that null is disallowed as an input even if the corresponding type allows it. [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] #if USE_PUBLIC_LATEST_CSHARP_FEATURES public #else internal #endif - sealed class DisallowNullAttribute : Attribute { } + sealed class DisallowNullAttribute : Attribute { } - /// - /// 标记一个非空的返回值实际上可能会返回 null,返回值包括输出参数。 - /// + /// Specifies that an output may be null even if the corresponding type disallows it. [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] #if USE_PUBLIC_LATEST_CSHARP_FEATURES public #else internal #endif - sealed class MaybeNullAttribute : Attribute { } + sealed class MaybeNullAttribute : Attribute { } - /// - /// 标记一个可空的返回值实际上是不可能返回 null 的,返回值包括输出参数。 - /// + /// Specifies that an output will not be null even if the corresponding type allows it. Specifies that an input argument was not null when the call returns. [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] #if USE_PUBLIC_LATEST_CSHARP_FEATURES public #else internal #endif - sealed class NotNullAttribute : Attribute { } + sealed class NotNullAttribute : Attribute { } - /// - /// 当返回指定的 true/false 时某个输出参数才可能为 null,而返回相反的值时那个输出参数则不可为 null。 - /// + /// Specifies that when a method returns , the parameter may be null even if the corresponding type disallows it. [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] #if USE_PUBLIC_LATEST_CSHARP_FEATURES public #else internal #endif - sealed class MaybeNullWhenAttribute : Attribute + sealed class MaybeNullWhenAttribute : Attribute { - /// - /// 使用 true 或者 false 决定输出参数是否可能为 null。 - /// - /// 如果方法返回值等于这个值,那么输出参数则可能为 null,否则输出参数是不可为 null 的。 + /// Initializes the attribute with the specified return value condition. + /// + /// The return value condition. If the method returns this value, the associated parameter may be null. + /// public MaybeNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; - /// - /// 获取返回值决定是否可为空的那个判断值。 - /// + /// Gets the return value condition. public bool ReturnValue { get; } } - /// - /// 当返回指定的 true/false 时,某个输出参数不可为 null,而返回相反的值时那个输出参数则可能为 null。 - /// + /// Specifies that when a method returns , the parameter will not be null even if the corresponding type allows it. [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] #if USE_PUBLIC_LATEST_CSHARP_FEATURES public #else internal #endif - sealed class NotNullWhenAttribute : Attribute + sealed class NotNullWhenAttribute : Attribute { - /// - /// 使用 true 或者 false 决定输出参数是否不可为 null。 - /// + /// Initializes the attribute with the specified return value condition. /// - /// 如果方法或属性的返回值等于这个值,那么输出参数则不可为 null,否则输出参数是可能为 null 的。 + /// The return value condition. If the method returns this value, the associated parameter will not be null. /// public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; - /// - /// 获取返回值决定是否不可为空的那个判断值。 - /// + /// Gets the return value condition. public bool ReturnValue { get; } } - /// - /// 指定的参数传入 null 时才可能返回 null,指定的参数传入非 null 时就不可能返回 null。 - /// + /// Specifies that the output will be non-null if the named parameter is non-null. [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)] #if USE_PUBLIC_LATEST_CSHARP_FEATURES public #else internal #endif - sealed class NotNullIfNotNullAttribute : Attribute + sealed class NotNullIfNotNullAttribute : Attribute { - /// - /// 使用一个参数名称决定返回值是否可能为 null。 - /// + /// Initializes the attribute with the associated parameter name. /// - /// 指定一个方法传入参数的名称,当这个参数传入非 null 时,输出参数或者返回值就是非 null;而这个参数传入可为 null 时,输出参数或者返回值就可为 null。 + /// The associated parameter name. The output will be non-null if the argument to the parameter specified is non-null. /// public NotNullIfNotNullAttribute(string parameterName) => ParameterName = parameterName; - /// - /// 获取决定输出参数或者返回值是否可能为空的那个参数名称。 - /// + /// Gets the associated parameter name. public string ParameterName { get; } } - /// - /// 指定一个方法是不可能返回的。 - /// + /// Applied to a method that will never return under any circumstance. [AttributeUsage(AttributeTargets.Method, Inherited = false)] #if USE_PUBLIC_LATEST_CSHARP_FEATURES public #else internal #endif - sealed class DoesNotReturnAttribute : Attribute { } + sealed class DoesNotReturnAttribute : Attribute { } - /// - /// 在方法的输入参数上指定一个条件,当这个参数传入了指定的 true/false 时方法不可能返回。 - /// + /// Specifies that the method will not return if the associated Boolean parameter is passed the specified value. [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] #if USE_PUBLIC_LATEST_CSHARP_FEATURES public #else internal #endif - sealed class DoesNotReturnIfAttribute : Attribute + sealed class DoesNotReturnIfAttribute : Attribute { - /// - /// 使用 true/false 决定方法是否可能返回。 - /// + /// Initializes the attribute with the specified parameter value. /// - /// 在方法的输入参数上指定一个条件,当这个参数传入的值等于这里设定的值时,方法不可能返回。 + /// The condition parameter value. Code after the method will be considered unreachable by diagnostics if the argument to + /// the associated parameter matches this value. /// public DoesNotReturnIfAttribute(bool parameterValue) => ParameterValue = parameterValue; - /// - /// 获取决定方法是否可返回的那个参数的值。 - /// + /// Gets the condition parameter value. public bool ParameterValue { get; } } #endif #if NET5_0_OR_GREATER #else - /// - /// 调用了此方法后,即可保证列表中所列出的字段和属性成员将不会为 null。 - /// + /// Specifies that the method or property will ensure that the listed field and property members have not-null values. [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] #if USE_PUBLIC_LATEST_CSHARP_FEATURES public #else internal #endif - sealed class MemberNotNullAttribute : Attribute + sealed class MemberNotNullAttribute : Attribute { - /// - /// 指定调用了此方法后,所列出的字段和属性成员将不会为 null。 - /// + /// Initializes the attribute with a field or property member. /// - /// 将保证不会为 null 的字段或属性名称。 + /// The field or property member that is promised to be not-null. /// public MemberNotNullAttribute(string member) => Members = new[] { member }; - /// - /// 指定调用了此方法后,所列出的字段和属性成员将不会为 null。 - /// + /// Initializes the attribute with the list of field and property members. /// - /// 将保证不会为 null 的字段或属性名称列表。 + /// The list of field and property members that are promised to be not-null. /// public MemberNotNullAttribute(params string[] members) => Members = members; - /// - /// 调用了此方法后保证不会为 null 的字段或属性名称列表。 - /// + /// Gets field or property member names. public string[] Members { get; } } - /// - /// 当返回指定的 true/false 时,即可保证列表中所列出的字段和属性成员将不会为 null。 - /// + /// Specifies that the method or property will ensure that the listed field and property members have not-null values when returning with the specified return value condition. [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] #if USE_PUBLIC_LATEST_CSHARP_FEATURES public #else internal #endif - sealed class MemberNotNullWhenAttribute : Attribute + sealed class MemberNotNullWhenAttribute : Attribute { - /// - /// 使用 true 或者 false 决定是否所列出的字段和属性成员将不会为 null。 - /// + /// Initializes the attribute with the specified return value condition and a field or property member. /// - /// 如果方法或属性的返回值等于这个值,那么所列出的字段和属性成员将不会为 null。 + /// The return value condition. If the method returns this value, the associated parameter will not be null. /// /// - /// 将保证不会为 null 的字段或属性名称列表。 + /// The field or property member that is promised to be not-null. /// public MemberNotNullWhenAttribute(bool returnValue, string member) { @@ -217,14 +177,12 @@ public MemberNotNullWhenAttribute(bool returnValue, string member) Members = new[] { member }; } - /// - /// 使用 true 或者 false 决定是否所列出的字段和属性成员将不会为 null。 - /// + /// Initializes the attribute with the specified return value condition and list of field and property members. /// - /// 如果方法或属性的返回值等于这个值,那么所列出的字段和属性成员将不会为 null。 + /// The return value condition. If the method returns this value, the associated parameter will not be null. /// /// - /// 将保证不会为 null 的字段或属性名称列表。 + /// The list of field and property members that are promised to be not-null. /// public MemberNotNullWhenAttribute(bool returnValue, params string[] members) { @@ -232,14 +190,10 @@ public MemberNotNullWhenAttribute(bool returnValue, params string[] members) Members = members; } - /// - /// 获取返回值决定是否不可为空的那个判断值。 - /// + /// Gets the return value condition. public bool ReturnValue { get; } - /// - /// 调用了此方法后保证不会为 null 的字段或属性名称列表。 - /// + /// Gets field or property member names. public string[] Members { get; } } #endif From 2e50f5fda02a3785440679c90f4c19e8c5263585 Mon Sep 17 00:00:00 2001 From: walterlv Date: Sat, 27 Apr 2024 10:48:26 +0800 Subject: [PATCH 05/23] Disable ValueTuple warning --- .../ValueTuple/ValueTuple.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/dotnetCampus.LatestCSharpFeatures/ValueTuple/ValueTuple.cs b/src/dotnetCampus.LatestCSharpFeatures/ValueTuple/ValueTuple.cs index d18c7ea..4a20ff3 100644 --- a/src/dotnetCampus.LatestCSharpFeatures/ValueTuple/ValueTuple.cs +++ b/src/dotnetCampus.LatestCSharpFeatures/ValueTuple/ValueTuple.cs @@ -1,4 +1,7 @@ -#if NETSTANDARD2_0_OR_GREATER || NETCOREAPP3_0 || NETCOREAPP3_1 || NET5_0_OR_GREATER +#pragma warning disable CS8600 +#pragma warning disable CS8603 + +#if NETSTANDARD2_0_OR_GREATER || NETCOREAPP3_0 || NETCOREAPP3_1 || NET5_0_OR_GREATER #else // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. From 94665f50bdb90aa731afb44f1101308af6acd21e Mon Sep 17 00:00:00 2001 From: walterlv Date: Sat, 27 Apr 2024 10:57:27 +0800 Subject: [PATCH 06/23] Fix compile --- Directory.Build.props | 5 +++-- .../dotnetCampus.LatestCSharpFeatures.csproj | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 61801d0..6da387d 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -15,9 +15,10 @@ - $(NoWarn);NETSDK1138;NU5100 + $(NoWarn);NETSDK1138;NU5100;NU5128 diff --git a/src/dotnetCampus.LatestCSharpFeatures/dotnetCampus.LatestCSharpFeatures.csproj b/src/dotnetCampus.LatestCSharpFeatures/dotnetCampus.LatestCSharpFeatures.csproj index b8d5677..d4f23fa 100644 --- a/src/dotnetCampus.LatestCSharpFeatures/dotnetCampus.LatestCSharpFeatures.csproj +++ b/src/dotnetCampus.LatestCSharpFeatures/dotnetCampus.LatestCSharpFeatures.csproj @@ -1,7 +1,7 @@  - net8.0;netcoreapp3.0;netstandard2.0;net40 + net8.0;netstandard2.0;net40 true System.Diagnostics.CodeAnalysis This comprehensive package provides support for the latest C# language features in your project, enabling older .NET projects to use newer C# language constructs. Currently includes support for 'nullable', 'init', and 'required' keywords. The types introduced are internal, confining these features to the project itself without affecting other projects that reference it. By installing this package, you get all the newest C# features in one place, eliminating the need to install separate packages for each feature. Future updates will include more new features as they are released. @@ -10,7 +10,7 @@ - + From 5536ad67fc81c3728ece6230edc4e2cb9ba06026 Mon Sep 17 00:00:00 2001 From: walterlv Date: Sat, 27 Apr 2024 11:00:28 +0800 Subject: [PATCH 07/23] =?UTF-8?q?=E4=BB=85=E4=B8=80=E4=B8=AA=E5=8C=85?= =?UTF-8?q?=EF=BC=8C=E4=BA=8E=E6=98=AF=E4=B8=8D=E9=9C=80=E8=A6=81=E5=9C=A8?= =?UTF-8?q?=E5=A4=96=E9=9D=A2=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Directory.Build.props | 5 ----- .../dotnetCampus.LatestCSharpFeatures.csproj | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 6da387d..b56a64e 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -32,9 +32,4 @@ https://github.com/dotnet-campus/dotnetCampus.LatestCSharpFeatures - - - - - diff --git a/src/dotnetCampus.LatestCSharpFeatures/dotnetCampus.LatestCSharpFeatures.csproj b/src/dotnetCampus.LatestCSharpFeatures/dotnetCampus.LatestCSharpFeatures.csproj index d4f23fa..484e7f3 100644 --- a/src/dotnetCampus.LatestCSharpFeatures/dotnetCampus.LatestCSharpFeatures.csproj +++ b/src/dotnetCampus.LatestCSharpFeatures/dotnetCampus.LatestCSharpFeatures.csproj @@ -8,6 +8,11 @@ false + + + + + From 3acc40e7aec8ae95c320994713a19fbbd86bafff Mon Sep 17 00:00:00 2001 From: walterlv Date: Sat, 27 Apr 2024 11:10:22 +0800 Subject: [PATCH 08/23] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dotnetCampus.LatestCSharpFeatures.Analyzer.csproj | 4 +--- .../dotnetCampus.LatestCSharpFeatures.csproj | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/dotnetCampus.LatestCSharpFeatures.Analyzer/dotnetCampus.LatestCSharpFeatures.Analyzer.csproj b/src/dotnetCampus.LatestCSharpFeatures.Analyzer/dotnetCampus.LatestCSharpFeatures.Analyzer.csproj index ca1c98d..a092e2d 100644 --- a/src/dotnetCampus.LatestCSharpFeatures.Analyzer/dotnetCampus.LatestCSharpFeatures.Analyzer.csproj +++ b/src/dotnetCampus.LatestCSharpFeatures.Analyzer/dotnetCampus.LatestCSharpFeatures.Analyzer.csproj @@ -10,14 +10,12 @@ - + - - diff --git a/src/dotnetCampus.LatestCSharpFeatures/dotnetCampus.LatestCSharpFeatures.csproj b/src/dotnetCampus.LatestCSharpFeatures/dotnetCampus.LatestCSharpFeatures.csproj index 484e7f3..9e0653e 100644 --- a/src/dotnetCampus.LatestCSharpFeatures/dotnetCampus.LatestCSharpFeatures.csproj +++ b/src/dotnetCampus.LatestCSharpFeatures/dotnetCampus.LatestCSharpFeatures.csproj @@ -9,7 +9,7 @@ - + From b95bfc5890d94d75fa25f20289b48e35b629bfe4 Mon Sep 17 00:00:00 2001 From: walterlv Date: Sat, 27 Apr 2024 11:39:21 +0800 Subject: [PATCH 09/23] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=94=9F=E6=88=90?= =?UTF-8?q?=E7=9A=84=E7=B1=BB=E4=B8=8D=E5=85=A8=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FeatureGenerator.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/dotnetCampus.LatestCSharpFeatures.Analyzer/FeatureGenerator.cs b/src/dotnetCampus.LatestCSharpFeatures.Analyzer/FeatureGenerator.cs index 437216e..99a2468 100644 --- a/src/dotnetCampus.LatestCSharpFeatures.Analyzer/FeatureGenerator.cs +++ b/src/dotnetCampus.LatestCSharpFeatures.Analyzer/FeatureGenerator.cs @@ -19,8 +19,16 @@ public void Initialize(IncrementalGeneratorInitializationContext context) private void OnExecute(SourceProductionContext context, AnalyzerConfigOptionsProvider provider) { - GenerateFeatureSource(context, provider, "IsExternalInit"); + // .NET Core 1.0 / .NET Framework 4.7 / .NET Standard 2.0 才开始支持 ValueTuple。 + GenerateFeatureSource(context, provider, "ValueTuple"); + + // .NET Core 3.0 / .NET Standard 2.1 才开始支持 Nullable;.NET 5.0 开始支持更多。 GenerateFeatureSource(context, provider, "Nullable"); + + // .NET 5.0 才开始支持 ExternalInit + GenerateFeatureSource(context, provider, "ExternalInit"); + + // .NET 7.0 才开始支持 SetsRequiredMembersAttribute GenerateFeatureSource(context, provider, "Required"); } From a9a4cb0d7ca73fcdd25a4d4fded73c0dc65e5153 Mon Sep 17 00:00:00 2001 From: walterlv Date: Sat, 27 Apr 2024 11:42:13 +0800 Subject: [PATCH 10/23] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20net8.0=20=E7=9A=84?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dotnetCampus.LatestCSharpFeatures.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/dotnetCampus.LatestCSharpFeatures.Tests/dotnetCampus.LatestCSharpFeatures.Tests.csproj b/tests/dotnetCampus.LatestCSharpFeatures.Tests/dotnetCampus.LatestCSharpFeatures.Tests.csproj index 329fd93..4c973a2 100644 --- a/tests/dotnetCampus.LatestCSharpFeatures.Tests/dotnetCampus.LatestCSharpFeatures.Tests.csproj +++ b/tests/dotnetCampus.LatestCSharpFeatures.Tests/dotnetCampus.LatestCSharpFeatures.Tests.csproj @@ -1,7 +1,7 @@  - net7.0;net6.0;net5.0;netcoreapp3.1;netcoreapp3.0;netstandard2.0;net48;net472;net471;net47;net462;net461;net46;net452;net451;net45;net40 + net8.0;net7.0;net6.0;net5.0;netcoreapp3.1;netcoreapp3.0;netstandard2.0;net48;net472;net471;net47;net462;net461;net46;net452;net451;net45;net40 disable enable false From ae5caec0a49ff5018b11356d71a539c6fbba1022 Mon Sep 17 00:00:00 2001 From: walterlv Date: Sat, 27 Apr 2024 11:59:07 +0800 Subject: [PATCH 11/23] Update docs. --- README.md | 38 ++++++++++------------------------ build/Version.props | 4 ++-- docs/README.jp.md | 47 ------------------------------------------- docs/README.zh-CHS.md | 40 ++++++++++++++---------------------- docs/README.zh-CHT.md | 42 ++++++++++++-------------------------- 5 files changed, 41 insertions(+), 130 deletions(-) delete mode 100644 docs/README.jp.md diff --git a/README.md b/README.md index b41f577..9d077df 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,31 @@ # Latest CSharp Features -| Language | -| --- | +| Language | +| ---------------------------------- | | [简体中文](/docs/README.zh-CHS.md) | | [繁體中文](/docs/README.zh-CHT.md) | -| [English](/README.md) | -| [日本語](/docs/README.jp.md) | +| [English](/README.md) | -This open-source project provides a series of NuGet packages that allow you to use the latest C# language features in older versions of .NET (including older .NET Framework, .NET Standard, as well as older .NET Core App, .NET). +[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.LatestCSharpFeatures.svg)](https://www.nuget.org/packages/dotnetCampus.LatestCSharpFeatures) -## NuGet Packages - -We currently offer 8 NuGet packages for you to choose from based on your needs. - -|Package Name|Function|Link| -|---|---|---| -|dotnetCampus.LatestCSharpFeatures|All-in-one package, includes all new C# features|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.LatestCSharpFeatures.svg)](https://www.nuget.org/packages/dotnetCampus.LatestCSharpFeatures)| -|dotnetCampus.LatestCSharpFeatures.Source|Source code version of the all-in-one package|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.LatestCSharpFeatures.Source.svg)](https://www.nuget.org/packages/dotnetCampus.LatestCSharpFeatures.Source)| -|dotnetCampus.IsExternalInit|Supports the use of init syntax|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.IsExternalInit.svg)](https://www.nuget.org/packages/dotnetCampus.IsExternalInit)| -|dotnetCampus.IsExternalInit.Source|Source code version that supports the use of init syntax|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.IsExternalInit.Source.svg)](https://www.nuget.org/packages/dotnetCampus.IsExternalInit.Source)| -|dotnetCampus.Nullable|Supports the use of rich nullable features|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.Nullable.svg)](https://www.nuget.org/packages/dotnetCampus.Nullable)| -|dotnetCampus.Nullable.Source|Source code version that supports the use of rich nullable features|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.Nullable.Source.svg)](https://www.nuget.org/packages/dotnetCampus.Nullable.Source)| -|dotnetCampus.Required|Adds support for the required syntax*|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.Required.svg)](https://www.nuget.org/packages/dotnetCampus.Required)| -|dotnetCampus.Required.Source|Source code version that adds support for the required syntax*|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.Required.Source.svg)](https://www.nuget.org/packages/dotnetCampus.Required.Source)| - -\* For an introduction to the required syntax, you can refer to this [description](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/required)【7†source】【9†source】. +This open-source project provides a NuGet package, dotnetCampus.LatestCSharpFeatures, which allows you to use the latest C# language features in older versions of .NET, including the old .NET Framework, .NET Standard, and older versions of .NET Core App and .NET. ## How to Use -For both the all-in-one package and the single-feature packages, we provide two versions. Packages without the .Source suffix will generate a dll, so all projects that reference this project can use these new features. Packages with the .Source suffix are only effective for the project where the package is installed, and there are no additional dlls in the final generated project. +Simply install the dotnetCampus.LatestCSharpFeatures NuGet package. -If you want the .Source package to be effective for other projects that reference this project, you can add a conditional compilation symbol in the csproj file: +If you want these new language features to also be effective for other projects that reference this project, you can add a conditional compilation symbol in the csproj file: ```xml - + $(DefineConstants);USE_PUBLIC_LATEST_CSHARP_FEATURES ``` ## Feedback and Contributions -We welcome feedback and contributions from all users. If you encounter any problems during use, or have any suggestions for improvement, you can submit them via GitHub Issues. +We welcome feedback and contributions from all users. If you encounter any problems during use, or have any suggestions for improvements, you can submit them via GitHub Issues. -If you wish to participate in the development of the project, you are very welcome! You can Fork this repository and then submit a Pull Request. +If you wish to participate in the development of the project, you are also very welcome! You can Fork this repository and then submit a Pull Request. Thank you for your support and help with dotnetCampus.LatestCSharpFeatures! diff --git a/build/Version.props b/build/Version.props index 2b6ae1d..d2dfc45 100644 --- a/build/Version.props +++ b/build/Version.props @@ -1,5 +1,5 @@ - 11.0.0 + 12.0.0-alpha01 - \ No newline at end of file + diff --git a/docs/README.jp.md b/docs/README.jp.md deleted file mode 100644 index 007625b..0000000 --- a/docs/README.jp.md +++ /dev/null @@ -1,47 +0,0 @@ -# 最新のCSharpの特徴 - -| Language | -| --- | -| [简体中文](/docs/README.zh-CHS.md) | -| [繁體中文](/docs/README.zh-CHT.md) | -| [English](/README.md) | -| [日本語](/docs/README.jp.md) | - -このオープンソースプロジェクトは一連のNuGetパッケージを提供し、古いバージョンの.NET(古い.NET Framework、.NET Standard、古い.NET Core App、.NETを含む)で最新のC#言語の特徴を使用できます。 - -## NuGetパッケージ - -現在、8つのNuGetパッケージを提供しており、必要に応じて選択してインストールできます。 - -|パッケージ名|機能|リンク| -|---|---|---| -|dotnetCampus.LatestCSharpFeatures|全機能パッケージ、すべての新しいC#機能が含まれています|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.LatestCSharpFeatures.svg)](https://www.nuget.org/packages/dotnetCampus.LatestCSharpFeatures)| -|dotnetCampus.LatestCSharpFeatures.Source|全機能パッケージのソースコードバージョン|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.LatestCSharpFeatures.Source.svg)](https://www.nuget.org/packages/dotnetCampus.LatestCSharpFeatures.Source)| -|dotnetCampus.IsExternalInit|init構文の使用をサポート|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.IsExternalInit.svg)](https://www.nuget.org/packages/dotnetCampus.IsExternalInit)| -|dotnetCampus.IsExternalInit.Source|init構文の使用をサポートするソースコードバージョン|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.IsExternalInit.Source.svg)](https://www.nuget.org/packages/dotnetCampus.IsExternalInit.Source)| -|dotnetCampus.Nullable|豊富なnull許容型の使用をサポート|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.Nullable.svg)](https://www.nuget.org/packages/dotnetCampus.Nullable)| -|dotnetCampus.Nullable.Source|豊富なnull許容型の使用をサポートするソースコードバージョン|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.Nullable.Source.svg)](https://www.nuget.org/packages/dotnetCampus.Nullable.Source)| -|dotnetCampus.Required|required構文のサポートを追加*|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.Required.svg)](https://www.nuget.org/packages/dotnetCampus.Required)| -|dotnetCampus.Required.Source|required構文のサポートを追加するソースコードバージョン*|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.Required.Source.svg)](https://www.nuget.org/packages/dotnetCampus.Required.Source)| - -\* required構文の紹介については、ここでの[説明](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/required)を参照してください【7†source】【9†source】。 - -## 使用方法 - -全機能パッケージでも単一機能パッケージでも、2つのバージョンを提供しています。.Sourceサフィックスがないパッケージはdllを生成し、このプロジェクトを参照したすべてのプロジェクトでこれらの新機能を使用できます。一方、.Sourceサフィックスが付いたパッケージは、このパッケージをインストールしたプロジェクトにのみ有効で、最終的に生成されたプロジェクトには追加のdllがありません。 - -.Sourceパッケージをこのプロジェクトを参照した他のプロジェクトにも有効にしたい場合は、csprojファイルに条件付きコンパイルシンボルを追加できます: - -```xml - -$(DefineConstants);USE_PUBLIC_LATEST_CSHARP_FEATURES -``` - -## フィードバックと貢献 - -すべてのユーザーからのフィードバックと貢献を歓迎します。何か問題が見つかった場合や改善の提案がある場合は、GitHub Issuesで提出してください。 - -プロジェクトの開発に参加したい場合も、大歓迎です!このリポジトリをフォークして、Pull Requestを提出できます。 - -dotnetCampus.LatestCSharpFeaturesへのご支援とご協力に感謝します! diff --git a/docs/README.zh-CHS.md b/docs/README.zh-CHS.md index 3ad06ed..bda8d7c 100644 --- a/docs/README.zh-CHS.md +++ b/docs/README.zh-CHS.md @@ -1,39 +1,29 @@ -# Latest CSharp Features +# Latest CSharp Features - 最新 C# 语言特性 -| Language | -| --- | +| Language | +| ---------------------------------- | | [简体中文](/docs/README.zh-CHS.md) | | [繁體中文](/docs/README.zh-CHT.md) | -| [English](/README.md) | -| [日本語](/docs/README.jp.md) | +| [English](/README.md) | -此开源项目提供一系列 NuGet 包,让您可以在旧版本的 .NET(包括旧的 .NET Framework、.NET Standard,以及旧的 .NET Core App、.NET)中,使用最新的 C# 语言特性。 +[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.LatestCSharpFeatures.svg)](https://www.nuget.org/packages/dotnetCampus.LatestCSharpFeatures) -## NuGet 包 - -我们目前提供 8 个 NuGet 包,您可以根据需要选择安装。 - -|包名|功能|链接| -|---|---|---| -|dotnetCampus.LatestCSharpFeatures|全功能包,包含所有 C# 新功能|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.LatestCSharpFeatures.svg)](https://www.nuget.org/packages/dotnetCampus.LatestCSharpFeatures)| -|dotnetCampus.LatestCSharpFeatures.Source|全功能包的源代码版本|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.LatestCSharpFeatures.Source.svg)](https://www.nuget.org/packages/dotnetCampus.LatestCSharpFeatures.Source)| -|dotnetCampus.IsExternalInit|支持使用 init 语法|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.IsExternalInit.svg)](https://www.nuget.org/packages/dotnetCampus.IsExternalInit)| -|dotnetCampus.IsExternalInit.Source|支持使用 init 语法的源代码版本|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.IsExternalInit.Source.svg)](https://www.nuget.org/packages/dotnetCampus.IsExternalInit.Source)| -|dotnetCampus.Nullable|支持使用丰富的可空支持|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.Nullable.svg)](https://www.nuget.org/packages/dotnetCampus.Nullable)| -|dotnetCampus.Nullable.Source|支持使用丰富的可空支持的源代码版本|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.Nullable.Source.svg)](https://www.nuget.org/packages/dotnetCampus.Nullable.Source)| -|dotnetCampus.Required|增加了 required 语法的支持*|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.Required.svg)](https://www.nuget.org/packages/dotnetCampus.Required)| -|dotnetCampus.Required.Source|增加了 required 语法支持的源代码版本*|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.Required.Source.svg)](https://www.nuget.org/packages/dotnetCampus.Required.Source)| - -\* 对于 required 语法的介绍,您可以参考这里的[说明](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/required)【7†source】【9†source】。 +此开源项目提供一个 NuGet 包 dotnetCampus.LatestCSharpFeatures,让您可以在旧版本的 .NET(包括旧的 .NET Framework、.NET Standard,以及旧的 .NET Core App、.NET)中,使用最新的 C# 语言特性。 ## 使用方法 -无论是全功能包还是单一功能包,我们都提供了两种版本。不带 .Source 后缀的包会生成一个 dll,这样所有引用了这个项目的项目都能使用到这些新功能。而带有 .Source 后缀的包则只对安装此包的项目有效,最终生成的项目中没有额外的 dll。 +直接安装 dotnetCampus.LatestCSharpFeatures NuGet 包即可。 + +```xml + + +``` -如果您希望 .Source 包对其他引用了此项目的项目也生效,可以在 csproj 文件中增加一个条件编译符: +如果你希望这些新语言特性对其他引用了此项目的项目也生效,可以在 csproj 文件中增加一个条件编译符: ```xml - $(DefineConstants);USE_PUBLIC_LATEST_CSHARP_FEATURES ``` diff --git a/docs/README.zh-CHT.md b/docs/README.zh-CHT.md index fc57134..cce2d4b 100644 --- a/docs/README.zh-CHT.md +++ b/docs/README.zh-CHT.md @@ -1,47 +1,31 @@ -# 最新的 CSharp 特性 +# Latest CSharp Features 最新的 C# 特性 -| Language | -| --- | +| Language | +| ---------------------------------- | | [简体中文](/docs/README.zh-CHS.md) | | [繁體中文](/docs/README.zh-CHT.md) | -| [English](/README.md) | -| [日本語](/docs/README.jp.md) | +| [English](/README.md) | -此開源項目提供一系列 NuGet 包,讓您可以在舊版本的 .NET(包括舊的 .NET Framework、.NET Standard,以及舊的 .NET Core App、.NET)中,使用最新的 C# 語言特性。 +[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.LatestCSharpFeatures.svg)](https://www.nuget.org/packages/dotnetCampus.LatestCSharpFeatures) -## NuGet 包 - -我們目前提供 8 個 NuGet 包,您可以根據需要選擇安裝。 - -|包名|功能|連結| -|---|---|---| -|dotnetCampus.LatestCSharpFeatures|全功能包,包含所有 C# 新功能|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.LatestCSharpFeatures.svg)](https://www.nuget.org/packages/dotnetCampus.LatestCSharpFeatures)| -|dotnetCampus.LatestCSharpFeatures.Source|全功能包的源碼版本|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.LatestCSharpFeatures.Source.svg)](https://www.nuget.org/packages/dotnetCampus.LatestCSharpFeatures.Source)| -|dotnetCampus.IsExternalInit|支援使用 init 語法|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.IsExternalInit.svg)](https://www.nuget.org/packages/dotnetCampus.IsExternalInit)| -|dotnetCampus.IsExternalInit.Source|支援使用 init 語法的源碼版本|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.IsExternalInit.Source.svg)](https://www.nuget.org/packages/dotnetCampus.IsExternalInit.Source)| -|dotnetCampus.Nullable|支援使用豐富的可空支援|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.Nullable.svg)](https://www.nuget.org/packages/dotnetCampus.Nullable)| -|dotnetCampus.Nullable.Source|支援使用豐富的可空支援的源碼版本|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.Nullable.Source.svg)](https://www.nuget.org/packages/dotnetCampus.Nullable.Source)| -|dotnetCampus.Required|增加了 required 語法的支援*|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.Required.svg)](https://www.nuget.org/packages/dotnetCampus.Required)| -|dotnetCampus.Required.Source|增加了 required 語法支援的源碼版本*|[![NuGet](https://img.shields.io/nuget/v/dotnetCampus.Required.Source.svg)](https://www.nuget.org/packages/dotnetCampus.Required.Source)| - -\* 對於 required 語法的介紹,您可以參考這裡的[說明](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/required)【7†source】【9†source】。 +此開源項目提供一個 NuGet 包 dotnetCampus.LatestCSharpFeatures,讓您可以在舊版本的 .NET(包括舊的 .NET Framework、.NET Standard,以及舊的 .NET Core App、.NET)中,使用最新的 C# 語言特性。 ## 使用方法 -無論是全功能包還是單一功能包,我們都提供了兩種版本。不帶 .Source 後綴的包會生成一個 dll,這樣所有引用了這個項目的項目都能使用到這些新功能。而帶有 .Source 後綴的包則只對安裝此包的項目有效,最終生成的項目中沒有額外的 dll。 +直接安裝 dotnetCampus.LatestCSharpFeatures NuGet 包即可。 -如果您希望 .Source 包對其他引用了此項目的項目也生效,可以在 csproj 文件中增加一個條件編譯符: +如果您希望這些新語言特性對其他引用了此項目的項目也生效,可以在 csproj 文件中增加一個條件編譯符: ```xml - + $(DefineConstants);USE_PUBLIC_LATEST_CSHARP_FEATURES ``` ## 反饋與貢獻 -我們歡迎所有用戶的反饋和貢獻。如果你在使用過程中發現任何問題,或者有任何改進建議,都可以通過 GitHub Issues 提交。 +我們歡迎所有用戶的反饋和貢獻。如果您在使用過程中發現任何問題,或者有任何改進建議,都可以通過 GitHub Issues 提交。 -如果你希望參與到項目的開發中,也非常歡迎!你可以 Fork 本倉庫,然後提交 Pull Request。 +如果您希望參與到項目的開發中,也非常歡迎!您可以 Fork 本倉庫,然後提交 Pull Request。 -感謝你對 dotnetCampus.LatestCSharpFeatures 的支援和幫助! +感謝您對 dotnetCampus.LatestCSharpFeatures 的支持和幫助! From 740a7e2e192bb508766e667b19969cfbd0e7cd2a Mon Sep 17 00:00:00 2001 From: walterlv Date: Sat, 27 Apr 2024 12:04:35 +0800 Subject: [PATCH 12/23] =?UTF-8?q?=E6=A0=87=E8=AE=B0=20C#=20=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build/Version.props | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build/Version.props b/build/Version.props index d2dfc45..64a7364 100644 --- a/build/Version.props +++ b/build/Version.props @@ -1,5 +1,6 @@ - 12.0.0-alpha01 + + 12.0.0 From 93a89d9bf575dcab1ce5397700cfd751cfc479ba Mon Sep 17 00:00:00 2001 From: walterlv Date: Sat, 27 Apr 2024 12:07:34 +0800 Subject: [PATCH 13/23] Fix doc comment --- README.md | 10 ++++++++-- docs/README.zh-CHT.md | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9d077df..5ebc36d 100644 --- a/README.md +++ b/README.md @@ -14,11 +14,17 @@ This open-source project provides a NuGet package, dotnetCampus.LatestCSharpFeat Simply install the dotnetCampus.LatestCSharpFeatures NuGet package. -If you want these new language features to also be effective for other projects that reference this project, you can add a conditional compilation symbol in the csproj file: - ```xml + +``` + +If you want these new language features to also be effective for other projects that reference this project, you can add a conditional compilation symbol in the csproj file: + +```xml + $(DefineConstants);USE_PUBLIC_LATEST_CSHARP_FEATURES ``` diff --git a/docs/README.zh-CHT.md b/docs/README.zh-CHT.md index cce2d4b..1987455 100644 --- a/docs/README.zh-CHT.md +++ b/docs/README.zh-CHT.md @@ -14,11 +14,17 @@ 直接安裝 dotnetCampus.LatestCSharpFeatures NuGet 包即可。 -如果您希望這些新語言特性對其他引用了此項目的項目也生效,可以在 csproj 文件中增加一個條件編譯符: - ```xml + +``` + +如果您希望這些新語言特性對其他引用了此項目的項目也生效,可以在 csproj 文件中增加一個條件編譯符: + +```xml + $(DefineConstants);USE_PUBLIC_LATEST_CSHARP_FEATURES ``` From 8314c75fca736db6c28492877286e904265fa66c Mon Sep 17 00:00:00 2001 From: walterlv Date: Sat, 27 Apr 2024 12:11:33 +0800 Subject: [PATCH 14/23] Fix CI --- .github/workflows/dotnet-build.yml | 7 ++-- .github/workflows/nuget-master-publish.yml | 40 ---------------------- .github/workflows/nuget-tag-publish.yml | 7 ++-- 3 files changed, 4 insertions(+), 50 deletions(-) delete mode 100644 .github/workflows/nuget-master-publish.yml diff --git a/.github/workflows/dotnet-build.yml b/.github/workflows/dotnet-build.yml index 63252ef..944b751 100644 --- a/.github/workflows/dotnet-build.yml +++ b/.github/workflows/dotnet-build.yml @@ -14,13 +14,10 @@ jobs: uses: actions/setup-dotnet@v1 with: dotnet-version: | - 3.1.x - 5.0.x - 6.0.x - 7.0.x + 8.0.x - name: Build with dotnet run: dotnet build --configuration Release - name: Test - run: dotnet test --configuration Release \ No newline at end of file + run: dotnet test --configuration Release diff --git a/.github/workflows/nuget-master-publish.yml b/.github/workflows/nuget-master-publish.yml deleted file mode 100644 index 9b5e85c..0000000 --- a/.github/workflows/nuget-master-publish.yml +++ /dev/null @@ -1,40 +0,0 @@ -# 去掉注释可以合并 master 分支自动打包 -# 为什么不期望推送 master 自动打包?原因是打出来的 CBB 没有 Tag 不利于回滚找到代码 - -# name: publish nuget - -# on: -# push: -# branches: -# - master - -# jobs: -# build: - -# runs-on: windows-latest - -# steps: -# - uses: actions/checkout@v1 - -# - name: Setup .NET Core -# uses: actions/setup-dotnet@v1 -# with: -# dotnet-version: 3.1.300 - -# - name: Build with dotnet -# run: | -# dotnet build --configuration Release -# dotnet pack --configuration Release --no-build - -# - name: Install Nuget -# uses: nuget/setup-nuget@v1 -# with: -# nuget-version: '5.x' - -# - name: Add private GitHub registry to NuGet -# run: | -# nuget sources add -name github -Source https://nuget.pkg.github.com/dotnet-campus/index.json -Username dotnet-campus -Password ${{ secrets.GITHUB_TOKEN }} -# - name: Push generated package to GitHub registry -# run: | -# nuget push .\bin\Release\*.nupkg -Source github -SkipDuplicate -# nuget push .\bin\Release\*.nupkg -Source https://api.nuget.org/v3/index.json -SkipDuplicate -ApiKey ${{ secrets.NugetKey }} diff --git a/.github/workflows/nuget-tag-publish.yml b/.github/workflows/nuget-tag-publish.yml index 566e99b..176706c 100644 --- a/.github/workflows/nuget-tag-publish.yml +++ b/.github/workflows/nuget-tag-publish.yml @@ -1,6 +1,6 @@ name: publish nuget -on: +on: push: tags: - '*' @@ -17,10 +17,7 @@ jobs: uses: actions/setup-dotnet@v1 with: dotnet-version: | - 3.1.x - 5.0.x - 6.0.x - 7.0.x + 8.0.x - name: Install dotnet tool run: dotnet tool install -g dotnetCampus.TagToVersion From a3c86511d2c24403010dc25bb37667ab4f49ef1d Mon Sep 17 00:00:00 2001 From: walterlv Date: Sat, 27 Apr 2024 12:30:35 +0800 Subject: [PATCH 15/23] Fix pack directory --- .github/workflows/dotnet-build.yml | 4 ++-- .github/workflows/nuget-tag-publish.yml | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dotnet-build.yml b/.github/workflows/dotnet-build.yml index 944b751..4490594 100644 --- a/.github/workflows/dotnet-build.yml +++ b/.github/workflows/dotnet-build.yml @@ -17,7 +17,7 @@ jobs: 8.0.x - name: Build with dotnet - run: dotnet build --configuration Release + run: dotnet build --configuration release - name: Test - run: dotnet test --configuration Release + run: dotnet test --configuration release diff --git a/.github/workflows/nuget-tag-publish.yml b/.github/workflows/nuget-tag-publish.yml index 176706c..2c7fbe9 100644 --- a/.github/workflows/nuget-tag-publish.yml +++ b/.github/workflows/nuget-tag-publish.yml @@ -27,8 +27,8 @@ jobs: - name: Build with dotnet run: | - dotnet build --configuration Release - dotnet pack --configuration Release --no-build + dotnet build --configuration release + dotnet pack --configuration release --no-build - name: Install Nuget uses: nuget/setup-nuget@v1 @@ -41,5 +41,5 @@ jobs: - name: Push generated package to GitHub registry run: | - nuget push .\bin\Release\*.nupkg -Source github -SkipDuplicate - nuget push .\bin\Release\*.nupkg -Source https://api.nuget.org/v3/index.json -SkipDuplicate -ApiKey ${{ secrets.NugetKey }} + nuget push .\artifacts\package\release\*.nupkg -Source github -SkipDuplicate + nuget push .\artifacts\package\release\*.nupkg -Source https://api.nuget.org/v3/index.json -SkipDuplicate -ApiKey ${{ secrets.NugetKey }} From 532033e314549c0ee280593accc937910c09d9b3 Mon Sep 17 00:00:00 2001 From: walterlv Date: Sat, 27 Apr 2024 12:35:04 +0800 Subject: [PATCH 16/23] Fix test --- .github/workflows/dotnet-build.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet-build.yml b/.github/workflows/dotnet-build.yml index 4490594..e02fd87 100644 --- a/.github/workflows/dotnet-build.yml +++ b/.github/workflows/dotnet-build.yml @@ -19,5 +19,6 @@ jobs: - name: Build with dotnet run: dotnet build --configuration release - - name: Test - run: dotnet test --configuration release +# No need because all tests passed if the solution is successfully built +# - name: Test +# run: dotnet test --configuration release From f8eeb0622802be1f566fcda81f9e4d708e2b3fe4 Mon Sep 17 00:00:00 2001 From: walterlv Date: Sat, 27 Apr 2024 12:48:55 +0800 Subject: [PATCH 17/23] Fix doc --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5ebc36d..bc96bb2 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,8 @@ This open-source project provides a NuGet package, dotnetCampus.LatestCSharpFeat Simply install the dotnetCampus.LatestCSharpFeatures NuGet package. ```xml - + ``` From fd5c6c5477da58ac977372859012aa15396d7027 Mon Sep 17 00:00:00 2001 From: walterlv Date: Sat, 27 Apr 2024 12:52:27 +0800 Subject: [PATCH 18/23] =?UTF-8?q?=E4=BD=BF=E7=94=A8=E9=A2=84=E5=8F=91?= =?UTF-8?q?=E5=B8=83=E5=8C=85=E8=BF=9B=E8=A1=8C=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dotnetCampus.LatestCSharpFeatures.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/dotnetCampus.LatestCSharpFeatures.Tests/dotnetCampus.LatestCSharpFeatures.Tests.csproj b/tests/dotnetCampus.LatestCSharpFeatures.Tests/dotnetCampus.LatestCSharpFeatures.Tests.csproj index 4c973a2..bec72bd 100644 --- a/tests/dotnetCampus.LatestCSharpFeatures.Tests/dotnetCampus.LatestCSharpFeatures.Tests.csproj +++ b/tests/dotnetCampus.LatestCSharpFeatures.Tests/dotnetCampus.LatestCSharpFeatures.Tests.csproj @@ -17,7 +17,7 @@ - + From f2e9526bfde93597a4bce5d698f7fe32b151b419 Mon Sep 17 00:00:00 2001 From: walterlv Date: Sat, 27 Apr 2024 12:57:59 +0800 Subject: [PATCH 19/23] =?UTF-8?q?=E6=BA=90=E7=94=9F=E6=88=90=E5=99=A8?= =?UTF-8?q?=E4=BB=85=E5=AF=BC=E5=85=A5=E9=9C=80=E8=A6=81=E7=9A=84=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dotnetCampus.LatestCSharpFeatures.Analyzer.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dotnetCampus.LatestCSharpFeatures.Analyzer/dotnetCampus.LatestCSharpFeatures.Analyzer.csproj b/src/dotnetCampus.LatestCSharpFeatures.Analyzer/dotnetCampus.LatestCSharpFeatures.Analyzer.csproj index a092e2d..21a2843 100644 --- a/src/dotnetCampus.LatestCSharpFeatures.Analyzer/dotnetCampus.LatestCSharpFeatures.Analyzer.csproj +++ b/src/dotnetCampus.LatestCSharpFeatures.Analyzer/dotnetCampus.LatestCSharpFeatures.Analyzer.csproj @@ -14,7 +14,7 @@ - + From 722601b1b6a829ae444cc60572d8db971adedc34 Mon Sep 17 00:00:00 2001 From: walterlv Date: Sat, 27 Apr 2024 13:05:28 +0800 Subject: [PATCH 20/23] net47 contains valuetuple --- src/dotnetCampus.LatestCSharpFeatures/ValueTuple/ValueTuple.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dotnetCampus.LatestCSharpFeatures/ValueTuple/ValueTuple.cs b/src/dotnetCampus.LatestCSharpFeatures/ValueTuple/ValueTuple.cs index 4a20ff3..5840c25 100644 --- a/src/dotnetCampus.LatestCSharpFeatures/ValueTuple/ValueTuple.cs +++ b/src/dotnetCampus.LatestCSharpFeatures/ValueTuple/ValueTuple.cs @@ -1,7 +1,7 @@ #pragma warning disable CS8600 #pragma warning disable CS8603 -#if NETSTANDARD2_0_OR_GREATER || NETCOREAPP3_0 || NETCOREAPP3_1 || NET5_0_OR_GREATER +#if NETCOREAPP3_0 || NETCOREAPP3_1 || NET5_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER || NET47 || NET471 || NET472 || NET48 || NET481 #else // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. From a9295099849e9543226936a3972d90eb30a04854 Mon Sep 17 00:00:00 2001 From: walterlv Date: Sat, 27 Apr 2024 14:34:47 +0800 Subject: [PATCH 21/23] =?UTF-8?q?=E7=A7=BB=E9=99=A4=20ValueTuple=EF=BC=8C?= =?UTF-8?q?=E5=90=A6=E5=88=99=E5=A4=9A=E4=B8=AA=E4=BD=BF=E7=94=A8=E4=BA=86?= =?UTF-8?q?=E6=AD=A4=E5=8C=85=E7=9A=84=E5=BA=93=E5=B0=86=E5=87=BA=E7=8E=B0?= =?UTF-8?q?=E5=86=B2=E7=AA=81=E7=9A=84=E5=85=83=E7=BB=84=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ValueTuple/TupleElementNamesAttribute.cs | 66 - .../ValueTuple/ValueTuple.cs | 2365 ----------------- 2 files changed, 2431 deletions(-) delete mode 100644 src/dotnetCampus.LatestCSharpFeatures/ValueTuple/TupleElementNamesAttribute.cs delete mode 100644 src/dotnetCampus.LatestCSharpFeatures/ValueTuple/ValueTuple.cs diff --git a/src/dotnetCampus.LatestCSharpFeatures/ValueTuple/TupleElementNamesAttribute.cs b/src/dotnetCampus.LatestCSharpFeatures/ValueTuple/TupleElementNamesAttribute.cs deleted file mode 100644 index 2a56706..0000000 --- a/src/dotnetCampus.LatestCSharpFeatures/ValueTuple/TupleElementNamesAttribute.cs +++ /dev/null @@ -1,66 +0,0 @@ -#if NETSTANDARD2_0_OR_GREATER || NETCOREAPP3_0 || NETCOREAPP3_1 || NET5_0_OR_GREATER -#else -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace System.Runtime.CompilerServices -{ - using System.Collections.Generic; - - /// - /// Indicates that the use of on a member is meant to be treated as a tuple with element names. - /// - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue | AttributeTargets.Class | AttributeTargets.Struct )] - public sealed class TupleElementNamesAttribute : Attribute - { - private readonly string[] _transformNames; - - /// - /// Initializes a new instance of the class. - /// - /// - /// Specifies, in a prefix traversal of a type's - /// construction, which occurrences are meant to - /// carry element names. - /// - /// - /// This constructor is meant to be used on types that are built on an underlying - /// occurrence of that is meant to carry element names. - /// For instance, if C is a generic type with two type parameters, then a - /// use of the constructed type C{, - /// might be intended to treat the first type argument as a tuple with element names - /// and the second as a tuple without element names. In which case, the appropriate attribute - /// specification should use transformNames value of { "name1", "name2", null }. - /// - public TupleElementNamesAttribute(string[] transformNames) - { - if (transformNames == null) - { - throw new ArgumentNullException(nameof(transformNames)); - } - - _transformNames = transformNames; - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// When is created with this constructor, - /// it can be omitted instead. - /// - public TupleElementNamesAttribute() - { - _transformNames = new string[] { }; - } - - /// - /// Specifies, in a prefix traversal of a type's - /// construction, which occurrences are meant to - /// carry element names. - /// - public IList TransformNames => _transformNames; - } -} -#endif diff --git a/src/dotnetCampus.LatestCSharpFeatures/ValueTuple/ValueTuple.cs b/src/dotnetCampus.LatestCSharpFeatures/ValueTuple/ValueTuple.cs deleted file mode 100644 index 5840c25..0000000 --- a/src/dotnetCampus.LatestCSharpFeatures/ValueTuple/ValueTuple.cs +++ /dev/null @@ -1,2365 +0,0 @@ -#pragma warning disable CS8600 -#pragma warning disable CS8603 - -#if NETCOREAPP3_0 || NETCOREAPP3_1 || NET5_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER || NET47 || NET471 || NET472 || NET48 || NET481 -#else -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace System.Numerics.Hashing -{ - internal static class HashHelpers - { - public static readonly int RandomSeed = new Random().Next(Int32.MinValue, Int32.MaxValue); - - public static int Combine(int h1, int h2) - { - // RyuJIT optimizes this to use the ROL instruction - // Related GitHub pull request: dotnet/coreclr#1830 - uint rol5 = ((uint)h1 << 5) | ((uint)h1 >> 27); - return ((int)rol5 + h1) ^ h2; - } - } -} - -namespace System.Runtime.CompilerServices -{ - /// - /// This interface is required for types that want to be indexed into by dynamic patterns. - /// - public interface ITuple - { - /// - /// The number of positions in this data structure. - /// - int Length { get; } - - /// - /// Get the element at position . - /// - object this[int index] { get; } - } -} - -namespace System -{ - using System.Collections; - using System.Collections.Generic; - using System.Diagnostics.Contracts; - using System.Runtime.InteropServices; - using System.Runtime.CompilerServices; - using HashHelpers = System.Numerics.Hashing.HashHelpers; - - /// - /// Helper so we can call some tuple methods recursively without knowing the underlying types. - /// - internal interface IValueTupleInternal : ITuple - { - int GetHashCode(IEqualityComparer comparer); - string ToStringEnd(); - } - - /// - /// The ValueTuple types (from arity 0 to 8) comprise the runtime implementation that underlies tuples in C# and struct tuples in F#. - /// Aside from created via language syntax, they are most easily created via the ValueTuple.Create factory methods. - /// The System.ValueTuple types differ from the System.Tuple types in that: - /// - they are structs rather than classes, - /// - they are mutable rather than readonly, and - /// - their members (such as Item1, Item2, etc) are fields rather than properties. - /// - [Serializable] - public struct ValueTuple - : IEquatable, IStructuralEquatable, IStructuralComparable, IComparable, IComparable, IValueTupleInternal, ITuple - { - /// - /// Returns a value that indicates whether the current instance is equal to a specified object. - /// - /// The object to compare with this instance. - /// if is a . - public override bool Equals(object obj) - { - return obj is ValueTuple; - } - - /// Returns a value indicating whether this instance is equal to a specified value. - /// An instance to compare to this instance. - /// true if has the same value as this instance; otherwise, false. - public bool Equals(ValueTuple other) - { - return true; - } - - bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) - { - return other is ValueTuple; - } - - int IComparable.CompareTo(object other) - { - if (other == null) return 1; - - if (!(other is ValueTuple)) - { - throw new ArgumentException(); - } - - return 0; - } - - /// Compares this instance to a specified instance and returns an indication of their relative values. - /// An instance to compare. - /// - /// A signed number indicating the relative values of this instance and . - /// Returns less than zero if this instance is less than , zero if this - /// instance is equal to , and greater than zero if this instance is greater - /// than . - /// - public int CompareTo(ValueTuple other) - { - return 0; - } - - int IStructuralComparable.CompareTo(object other, IComparer comparer) - { - if (other == null) return 1; - - if (!(other is ValueTuple)) - { - throw new ArgumentException(); - } - - return 0; - } - - /// Returns the hash code for this instance. - /// A 32-bit signed integer hash code. - public override int GetHashCode() - { - return 0; - } - - int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) - { - return 0; - } - - int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) - { - return 0; - } - - /// - /// Returns a string that represents the value of this instance. - /// - /// The string representation of this instance. - /// - /// The string returned by this method takes the form (). - /// - public override string ToString() - { - return "()"; - } - - string IValueTupleInternal.ToStringEnd() - { - return ")"; - } - - /// - /// The number of positions in this data structure. - /// - int ITuple.Length => 0; - - /// - /// Get the element at position . - /// - object ITuple.this[int index] - { - get - { - throw new IndexOutOfRangeException(); - } - } - - /// Creates a new struct 0-tuple. - /// A 0-tuple. - public static ValueTuple Create() => - new ValueTuple(); - - /// Creates a new struct 1-tuple, or singleton. - /// The type of the first component of the tuple. - /// The value of the first component of the tuple. - /// A 1-tuple (singleton) whose value is (item1). - public static ValueTuple Create(T1 item1) => - new ValueTuple(item1); - - /// Creates a new struct 2-tuple, or pair. - /// The type of the first component of the tuple. - /// The type of the second component of the tuple. - /// The value of the first component of the tuple. - /// The value of the second component of the tuple. - /// A 2-tuple (pair) whose value is (item1, item2). - public static ValueTuple Create(T1 item1, T2 item2) => - new ValueTuple(item1, item2); - - /// Creates a new struct 3-tuple, or triple. - /// The type of the first component of the tuple. - /// The type of the second component of the tuple. - /// The type of the third component of the tuple. - /// The value of the first component of the tuple. - /// The value of the second component of the tuple. - /// The value of the third component of the tuple. - /// A 3-tuple (triple) whose value is (item1, item2, item3). - public static ValueTuple Create(T1 item1, T2 item2, T3 item3) => - new ValueTuple(item1, item2, item3); - - /// Creates a new struct 4-tuple, or quadruple. - /// The type of the first component of the tuple. - /// The type of the second component of the tuple. - /// The type of the third component of the tuple. - /// The type of the fourth component of the tuple. - /// The value of the first component of the tuple. - /// The value of the second component of the tuple. - /// The value of the third component of the tuple. - /// The value of the fourth component of the tuple. - /// A 4-tuple (quadruple) whose value is (item1, item2, item3, item4). - public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4) => - new ValueTuple(item1, item2, item3, item4); - - /// Creates a new struct 5-tuple, or quintuple. - /// The type of the first component of the tuple. - /// The type of the second component of the tuple. - /// The type of the third component of the tuple. - /// The type of the fourth component of the tuple. - /// The type of the fifth component of the tuple. - /// The value of the first component of the tuple. - /// The value of the second component of the tuple. - /// The value of the third component of the tuple. - /// The value of the fourth component of the tuple. - /// The value of the fifth component of the tuple. - /// A 5-tuple (quintuple) whose value is (item1, item2, item3, item4, item5). - public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) => - new ValueTuple(item1, item2, item3, item4, item5); - - /// Creates a new struct 6-tuple, or sextuple. - /// The type of the first component of the tuple. - /// The type of the second component of the tuple. - /// The type of the third component of the tuple. - /// The type of the fourth component of the tuple. - /// The type of the fifth component of the tuple. - /// The type of the sixth component of the tuple. - /// The value of the first component of the tuple. - /// The value of the second component of the tuple. - /// The value of the third component of the tuple. - /// The value of the fourth component of the tuple. - /// The value of the fifth component of the tuple. - /// The value of the sixth component of the tuple. - /// A 6-tuple (sextuple) whose value is (item1, item2, item3, item4, item5, item6). - public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) => - new ValueTuple(item1, item2, item3, item4, item5, item6); - - /// Creates a new struct 7-tuple, or septuple. - /// The type of the first component of the tuple. - /// The type of the second component of the tuple. - /// The type of the third component of the tuple. - /// The type of the fourth component of the tuple. - /// The type of the fifth component of the tuple. - /// The type of the sixth component of the tuple. - /// The type of the seventh component of the tuple. - /// The value of the first component of the tuple. - /// The value of the second component of the tuple. - /// The value of the third component of the tuple. - /// The value of the fourth component of the tuple. - /// The value of the fifth component of the tuple. - /// The value of the sixth component of the tuple. - /// The value of the seventh component of the tuple. - /// A 7-tuple (septuple) whose value is (item1, item2, item3, item4, item5, item6, item7). - public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) => - new ValueTuple(item1, item2, item3, item4, item5, item6, item7); - - /// Creates a new struct 8-tuple, or octuple. - /// The type of the first component of the tuple. - /// The type of the second component of the tuple. - /// The type of the third component of the tuple. - /// The type of the fourth component of the tuple. - /// The type of the fifth component of the tuple. - /// The type of the sixth component of the tuple. - /// The type of the seventh component of the tuple. - /// The type of the eighth component of the tuple. - /// The value of the first component of the tuple. - /// The value of the second component of the tuple. - /// The value of the third component of the tuple. - /// The value of the fourth component of the tuple. - /// The value of the fifth component of the tuple. - /// The value of the sixth component of the tuple. - /// The value of the seventh component of the tuple. - /// The value of the eighth component of the tuple. - /// An 8-tuple (octuple) whose value is (item1, item2, item3, item4, item5, item6, item7, item8). - public static ValueTuple> Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8) => - new ValueTuple>(item1, item2, item3, item4, item5, item6, item7, ValueTuple.Create(item8)); - - internal static int CombineHashCodes(int h1, int h2) - { - return HashHelpers.Combine(HashHelpers.Combine(HashHelpers.RandomSeed, h1), h2); - } - - internal static int CombineHashCodes(int h1, int h2, int h3) - { - return HashHelpers.Combine(CombineHashCodes(h1, h2), h3); - } - - internal static int CombineHashCodes(int h1, int h2, int h3, int h4) - { - return HashHelpers.Combine(CombineHashCodes(h1, h2, h3), h4); - } - - internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5) - { - return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4), h5); - } - - internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6) - { - return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5), h6); - } - - internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7) - { - return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5, h6), h7); - } - - internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8) - { - return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5, h6, h7), h8); - } - } - - /// Represents a 1-tuple, or singleton, as a value type. - /// The type of the tuple's only component. - [Serializable] - public struct ValueTuple - : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple - { - /// - /// The current instance's first component. - /// - public T1 Item1; - - /// - /// Initializes a new instance of the value type. - /// - /// The value of the tuple's first component. - public ValueTuple(T1 item1) - { - Item1 = item1; - } - - /// - /// Returns a value that indicates whether the current instance is equal to a specified object. - /// - /// The object to compare with this instance. - /// if the current instance is equal to the specified object; otherwise, . - /// - /// The parameter is considered to be equal to the current instance under the following conditions: - /// - /// It is a value type. - /// Its components are of the same types as those of the current instance. - /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. - /// - /// - public override bool Equals(object obj) - { - return obj is ValueTuple && Equals((ValueTuple)obj); - } - - /// - /// Returns a value that indicates whether the current - /// instance is equal to a specified . - /// - /// The tuple to compare with this instance. - /// if the current instance is equal to the specified tuple; otherwise, . - /// - /// The parameter is considered to be equal to the current instance if each of its field - /// is equal to that of the current instance, using the default comparer for that field's type. - /// - public bool Equals(ValueTuple other) - { - return EqualityComparer.Default.Equals(Item1, other.Item1); - } - - bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) - { - if (other == null || !(other is ValueTuple)) return false; - - var objTuple = (ValueTuple)other; - - return comparer.Equals(Item1, objTuple.Item1); - } - - int IComparable.CompareTo(object other) - { - if (other == null) return 1; - - if (!(other is ValueTuple)) - { - throw new ArgumentException(); - } - - var objTuple = (ValueTuple)other; - - return Comparer.Default.Compare(Item1, objTuple.Item1); - } - - /// Compares this instance to a specified instance and returns an indication of their relative values. - /// An instance to compare. - /// - /// A signed number indicating the relative values of this instance and . - /// Returns less than zero if this instance is less than , zero if this - /// instance is equal to , and greater than zero if this instance is greater - /// than . - /// - public int CompareTo(ValueTuple other) - { - return Comparer.Default.Compare(Item1, other.Item1); - } - - int IStructuralComparable.CompareTo(object other, IComparer comparer) - { - if (other == null) return 1; - - if (!(other is ValueTuple)) - { - throw new ArgumentException(); - } - - var objTuple = (ValueTuple)other; - - return comparer.Compare(Item1, objTuple.Item1); - } - - /// - /// Returns the hash code for the current instance. - /// - /// A 32-bit signed integer hash code. - public override int GetHashCode() - { - return Item1?.GetHashCode() ?? 0; - } - - int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) - { - return comparer.GetHashCode(Item1); - } - - int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) - { - return comparer.GetHashCode(Item1); - } - - /// - /// Returns a string that represents the value of this instance. - /// - /// The string representation of this instance. - /// - /// The string returned by this method takes the form (Item1), - /// where Item1 represents the value of . If the field is , - /// it is represented as . - /// - public override string ToString() - { - return "(" + Item1?.ToString() + ")"; - } - - string IValueTupleInternal.ToStringEnd() - { - return Item1?.ToString() + ")"; - } - - /// - /// The number of positions in this data structure. - /// - int ITuple.Length => 1; - - /// - /// Get the element at position . - /// - object ITuple.this[int index] - { - get - { - if (index != 0) - { - throw new IndexOutOfRangeException(); - } - return Item1; - } - } - } - - /// - /// Represents a 2-tuple, or pair, as a value type. - /// - /// The type of the tuple's first component. - /// The type of the tuple's second component. - [Serializable] - [StructLayout(LayoutKind.Auto)] - public struct ValueTuple - : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple - { - /// - /// The current instance's first component. - /// - public T1 Item1; - - /// - /// The current instance's first component. - /// - public T2 Item2; - - /// - /// Initializes a new instance of the value type. - /// - /// The value of the tuple's first component. - /// The value of the tuple's second component. - public ValueTuple(T1 item1, T2 item2) - { - Item1 = item1; - Item2 = item2; - } - - /// - /// Returns a value that indicates whether the current instance is equal to a specified object. - /// - /// The object to compare with this instance. - /// if the current instance is equal to the specified object; otherwise, . - /// - /// - /// The parameter is considered to be equal to the current instance under the following conditions: - /// - /// It is a value type. - /// Its components are of the same types as those of the current instance. - /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. - /// - /// - public override bool Equals(object obj) - { - return obj is ValueTuple && Equals((ValueTuple)obj); - } - - /// - /// Returns a value that indicates whether the current instance is equal to a specified . - /// - /// The tuple to compare with this instance. - /// if the current instance is equal to the specified tuple; otherwise, . - /// - /// The parameter is considered to be equal to the current instance if each of its fields - /// are equal to that of the current instance, using the default comparer for that field's type. - /// - public bool Equals(ValueTuple other) - { - return EqualityComparer.Default.Equals(Item1, other.Item1) - && EqualityComparer.Default.Equals(Item2, other.Item2); - } - - /// - /// Returns a value that indicates whether the current instance is equal to a specified object based on a specified comparison method. - /// - /// The object to compare with this instance. - /// An object that defines the method to use to evaluate whether the two objects are equal. - /// if the current instance is equal to the specified object; otherwise, . - /// - /// - /// This member is an explicit interface member implementation. It can be used only when the - /// instance is cast to an interface. - /// - /// The implementation is called only if other is not , - /// and if it can be successfully cast (in C#) or converted (in Visual Basic) to a - /// whose components are of the same types as those of the current instance. The IStructuralEquatable.Equals(Object, IEqualityComparer) method - /// first passes the values of the objects to be compared to the - /// implementation. If this method call returns , the method is - /// called again and passed the values of the two instances. - /// - bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) - { - if (other == null || !(other is ValueTuple)) return false; - - var objTuple = (ValueTuple)other; - - return comparer.Equals(Item1, objTuple.Item1) - && comparer.Equals(Item2, objTuple.Item2); - } - - int IComparable.CompareTo(object other) - { - if (other == null) return 1; - - if (!(other is ValueTuple)) - { - throw new ArgumentException(); - } - - return CompareTo((ValueTuple)other); - } - - /// Compares this instance to a specified instance and returns an indication of their relative values. - /// An instance to compare. - /// - /// A signed number indicating the relative values of this instance and . - /// Returns less than zero if this instance is less than , zero if this - /// instance is equal to , and greater than zero if this instance is greater - /// than . - /// - public int CompareTo(ValueTuple other) - { - int c = Comparer.Default.Compare(Item1, other.Item1); - if (c != 0) return c; - - return Comparer.Default.Compare(Item2, other.Item2); - } - - int IStructuralComparable.CompareTo(object other, IComparer comparer) - { - if (other == null) return 1; - - if (!(other is ValueTuple)) - { - throw new ArgumentException(); - } - - var objTuple = (ValueTuple)other; - - int c = comparer.Compare(Item1, objTuple.Item1); - if (c != 0) return c; - - return comparer.Compare(Item2, objTuple.Item2); - } - - /// - /// Returns the hash code for the current instance. - /// - /// A 32-bit signed integer hash code. - public override int GetHashCode() - { - return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0, - Item2?.GetHashCode() ?? 0); - } - - int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) - { - return GetHashCodeCore(comparer); - } - - private int GetHashCodeCore(IEqualityComparer comparer) - { - return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), - comparer.GetHashCode(Item2)); - } - - int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) - { - return GetHashCodeCore(comparer); - } - - /// - /// Returns a string that represents the value of this instance. - /// - /// The string representation of this instance. - /// - /// The string returned by this method takes the form (Item1, Item2), - /// where Item1 and Item2 represent the values of the - /// and fields. If either field value is , - /// it is represented as . - /// - public override string ToString() - { - return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ")"; - } - - string IValueTupleInternal.ToStringEnd() - { - return Item1?.ToString() + ", " + Item2?.ToString() + ")"; - } - - /// - /// The number of positions in this data structure. - /// - int ITuple.Length => 2; - - /// - /// Get the element at position . - /// - object ITuple.this[int index] - { - get - { - switch (index) - { - case 0: - return Item1; - case 1: - return Item2; - default: - throw new IndexOutOfRangeException(); - } - } - } - } - - /// - /// Represents a 3-tuple, or triple, as a value type. - /// - /// The type of the tuple's first component. - /// The type of the tuple's second component. - /// The type of the tuple's third component. - [Serializable] - [StructLayout(LayoutKind.Auto)] - public struct ValueTuple - : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple - { - /// - /// The current instance's first component. - /// - public T1 Item1; - /// - /// The current instance's second component. - /// - public T2 Item2; - /// - /// The current instance's third component. - /// - public T3 Item3; - - /// - /// Initializes a new instance of the value type. - /// - /// The value of the tuple's first component. - /// The value of the tuple's second component. - /// The value of the tuple's third component. - public ValueTuple(T1 item1, T2 item2, T3 item3) - { - Item1 = item1; - Item2 = item2; - Item3 = item3; - } - - /// - /// Returns a value that indicates whether the current instance is equal to a specified object. - /// - /// The object to compare with this instance. - /// if the current instance is equal to the specified object; otherwise, . - /// - /// The parameter is considered to be equal to the current instance under the following conditions: - /// - /// It is a value type. - /// Its components are of the same types as those of the current instance. - /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. - /// - /// - public override bool Equals(object obj) - { - return obj is ValueTuple && Equals((ValueTuple)obj); - } - - /// - /// Returns a value that indicates whether the current - /// instance is equal to a specified . - /// - /// The tuple to compare with this instance. - /// if the current instance is equal to the specified tuple; otherwise, . - /// - /// The parameter is considered to be equal to the current instance if each of its fields - /// are equal to that of the current instance, using the default comparer for that field's type. - /// - public bool Equals(ValueTuple other) - { - return EqualityComparer.Default.Equals(Item1, other.Item1) - && EqualityComparer.Default.Equals(Item2, other.Item2) - && EqualityComparer.Default.Equals(Item3, other.Item3); - } - - bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) - { - if (other == null || !(other is ValueTuple)) return false; - - var objTuple = (ValueTuple)other; - - return comparer.Equals(Item1, objTuple.Item1) - && comparer.Equals(Item2, objTuple.Item2) - && comparer.Equals(Item3, objTuple.Item3); - } - - int IComparable.CompareTo(object other) - { - if (other == null) return 1; - - if (!(other is ValueTuple)) - { - throw new ArgumentException(); - } - - return CompareTo((ValueTuple)other); - } - - /// Compares this instance to a specified instance and returns an indication of their relative values. - /// An instance to compare. - /// - /// A signed number indicating the relative values of this instance and . - /// Returns less than zero if this instance is less than , zero if this - /// instance is equal to , and greater than zero if this instance is greater - /// than . - /// - public int CompareTo(ValueTuple other) - { - int c = Comparer.Default.Compare(Item1, other.Item1); - if (c != 0) return c; - - c = Comparer.Default.Compare(Item2, other.Item2); - if (c != 0) return c; - - return Comparer.Default.Compare(Item3, other.Item3); - } - - int IStructuralComparable.CompareTo(object other, IComparer comparer) - { - if (other == null) return 1; - - if (!(other is ValueTuple)) - { - throw new ArgumentException(); - } - - var objTuple = (ValueTuple)other; - - int c = comparer.Compare(Item1, objTuple.Item1); - if (c != 0) return c; - - c = comparer.Compare(Item2, objTuple.Item2); - if (c != 0) return c; - - return comparer.Compare(Item3, objTuple.Item3); - } - - /// - /// Returns the hash code for the current instance. - /// - /// A 32-bit signed integer hash code. - public override int GetHashCode() - { - return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0, - Item2?.GetHashCode() ?? 0, - Item3?.GetHashCode() ?? 0); - } - - int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) - { - return GetHashCodeCore(comparer); - } - - private int GetHashCodeCore(IEqualityComparer comparer) - { - return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), - comparer.GetHashCode(Item2), - comparer.GetHashCode(Item3)); - } - - int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) - { - return GetHashCodeCore(comparer); - } - - /// - /// Returns a string that represents the value of this instance. - /// - /// The string representation of this instance. - /// - /// The string returned by this method takes the form (Item1, Item2, Item3). - /// If any field value is , it is represented as . - /// - public override string ToString() - { - return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ")"; - } - - string IValueTupleInternal.ToStringEnd() - { - return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ")"; - } - - /// - /// The number of positions in this data structure. - /// - int ITuple.Length => 3; - - /// - /// Get the element at position . - /// - object ITuple.this[int index] - { - get - { - switch (index) - { - case 0: - return Item1; - case 1: - return Item2; - case 2: - return Item3; - default: - throw new IndexOutOfRangeException(); - } - } - } - } - - /// - /// Represents a 4-tuple, or quadruple, as a value type. - /// - /// The type of the tuple's first component. - /// The type of the tuple's second component. - /// The type of the tuple's third component. - /// The type of the tuple's fourth component. - [Serializable] - [StructLayout(LayoutKind.Auto)] - public struct ValueTuple - : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple - { - /// - /// The current instance's first component. - /// - public T1 Item1; - /// - /// The current instance's second component. - /// - public T2 Item2; - /// - /// The current instance's third component. - /// - public T3 Item3; - /// - /// The current instance's fourth component. - /// - public T4 Item4; - - /// - /// Initializes a new instance of the value type. - /// - /// The value of the tuple's first component. - /// The value of the tuple's second component. - /// The value of the tuple's third component. - /// The value of the tuple's fourth component. - public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4) - { - Item1 = item1; - Item2 = item2; - Item3 = item3; - Item4 = item4; - } - - /// - /// Returns a value that indicates whether the current instance is equal to a specified object. - /// - /// The object to compare with this instance. - /// if the current instance is equal to the specified object; otherwise, . - /// - /// The parameter is considered to be equal to the current instance under the following conditions: - /// - /// It is a value type. - /// Its components are of the same types as those of the current instance. - /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. - /// - /// - public override bool Equals(object obj) - { - return obj is ValueTuple && Equals((ValueTuple)obj); - } - - /// - /// Returns a value that indicates whether the current - /// instance is equal to a specified . - /// - /// The tuple to compare with this instance. - /// if the current instance is equal to the specified tuple; otherwise, . - /// - /// The parameter is considered to be equal to the current instance if each of its fields - /// are equal to that of the current instance, using the default comparer for that field's type. - /// - public bool Equals(ValueTuple other) - { - return EqualityComparer.Default.Equals(Item1, other.Item1) - && EqualityComparer.Default.Equals(Item2, other.Item2) - && EqualityComparer.Default.Equals(Item3, other.Item3) - && EqualityComparer.Default.Equals(Item4, other.Item4); - } - - bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) - { - if (other == null || !(other is ValueTuple)) return false; - - var objTuple = (ValueTuple)other; - - return comparer.Equals(Item1, objTuple.Item1) - && comparer.Equals(Item2, objTuple.Item2) - && comparer.Equals(Item3, objTuple.Item3) - && comparer.Equals(Item4, objTuple.Item4); - } - - int IComparable.CompareTo(object other) - { - if (other == null) return 1; - - if (!(other is ValueTuple)) - { - throw new ArgumentException(); - } - - return CompareTo((ValueTuple)other); - } - - /// Compares this instance to a specified instance and returns an indication of their relative values. - /// An instance to compare. - /// - /// A signed number indicating the relative values of this instance and . - /// Returns less than zero if this instance is less than , zero if this - /// instance is equal to , and greater than zero if this instance is greater - /// than . - /// - public int CompareTo(ValueTuple other) - { - int c = Comparer.Default.Compare(Item1, other.Item1); - if (c != 0) return c; - - c = Comparer.Default.Compare(Item2, other.Item2); - if (c != 0) return c; - - c = Comparer.Default.Compare(Item3, other.Item3); - if (c != 0) return c; - - return Comparer.Default.Compare(Item4, other.Item4); - } - - int IStructuralComparable.CompareTo(object other, IComparer comparer) - { - if (other == null) return 1; - - if (!(other is ValueTuple)) - { - throw new ArgumentException(); - } - - var objTuple = (ValueTuple)other; - - int c = comparer.Compare(Item1, objTuple.Item1); - if (c != 0) return c; - - c = comparer.Compare(Item2, objTuple.Item2); - if (c != 0) return c; - - c = comparer.Compare(Item3, objTuple.Item3); - if (c != 0) return c; - - return comparer.Compare(Item4, objTuple.Item4); - } - - /// - /// Returns the hash code for the current instance. - /// - /// A 32-bit signed integer hash code. - public override int GetHashCode() - { - return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0, - Item2?.GetHashCode() ?? 0, - Item3?.GetHashCode() ?? 0, - Item4?.GetHashCode() ?? 0); - } - - int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) - { - return GetHashCodeCore(comparer); - } - - private int GetHashCodeCore(IEqualityComparer comparer) - { - return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), - comparer.GetHashCode(Item2), - comparer.GetHashCode(Item3), - comparer.GetHashCode(Item4)); - } - - int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) - { - return GetHashCodeCore(comparer); - } - - /// - /// Returns a string that represents the value of this instance. - /// - /// The string representation of this instance. - /// - /// The string returned by this method takes the form (Item1, Item2, Item3, Item4). - /// If any field value is , it is represented as . - /// - public override string ToString() - { - return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ")"; - } - - string IValueTupleInternal.ToStringEnd() - { - return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ")"; - } - - /// - /// The number of positions in this data structure. - /// - int ITuple.Length => 4; - - /// - /// Get the element at position . - /// - object ITuple.this[int index] - { - get - { - switch (index) - { - case 0: - return Item1; - case 1: - return Item2; - case 2: - return Item3; - case 3: - return Item4; - default: - throw new IndexOutOfRangeException(); - } - } - } - } - - /// - /// Represents a 5-tuple, or quintuple, as a value type. - /// - /// The type of the tuple's first component. - /// The type of the tuple's second component. - /// The type of the tuple's third component. - /// The type of the tuple's fourth component. - /// The type of the tuple's fifth component. - [Serializable] - [StructLayout(LayoutKind.Auto)] - public struct ValueTuple - : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple - { - /// - /// The current instance's first component. - /// - public T1 Item1; - /// - /// The current instance's second component. - /// - public T2 Item2; - /// - /// The current instance's third component. - /// - public T3 Item3; - /// - /// The current instance's fourth component. - /// - public T4 Item4; - /// - /// The current instance's fifth component. - /// - public T5 Item5; - - /// - /// Initializes a new instance of the value type. - /// - /// The value of the tuple's first component. - /// The value of the tuple's second component. - /// The value of the tuple's third component. - /// The value of the tuple's fourth component. - /// The value of the tuple's fifth component. - public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) - { - Item1 = item1; - Item2 = item2; - Item3 = item3; - Item4 = item4; - Item5 = item5; - } - - /// - /// Returns a value that indicates whether the current instance is equal to a specified object. - /// - /// The object to compare with this instance. - /// if the current instance is equal to the specified object; otherwise, . - /// - /// The parameter is considered to be equal to the current instance under the following conditions: - /// - /// It is a value type. - /// Its components are of the same types as those of the current instance. - /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. - /// - /// - public override bool Equals(object obj) - { - return obj is ValueTuple && Equals((ValueTuple)obj); - } - - /// - /// Returns a value that indicates whether the current - /// instance is equal to a specified . - /// - /// The tuple to compare with this instance. - /// if the current instance is equal to the specified tuple; otherwise, . - /// - /// The parameter is considered to be equal to the current instance if each of its fields - /// are equal to that of the current instance, using the default comparer for that field's type. - /// - public bool Equals(ValueTuple other) - { - return EqualityComparer.Default.Equals(Item1, other.Item1) - && EqualityComparer.Default.Equals(Item2, other.Item2) - && EqualityComparer.Default.Equals(Item3, other.Item3) - && EqualityComparer.Default.Equals(Item4, other.Item4) - && EqualityComparer.Default.Equals(Item5, other.Item5); - } - - bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) - { - if (other == null || !(other is ValueTuple)) return false; - - var objTuple = (ValueTuple)other; - - return comparer.Equals(Item1, objTuple.Item1) - && comparer.Equals(Item2, objTuple.Item2) - && comparer.Equals(Item3, objTuple.Item3) - && comparer.Equals(Item4, objTuple.Item4) - && comparer.Equals(Item5, objTuple.Item5); - } - - int IComparable.CompareTo(object other) - { - if (other == null) return 1; - - if (!(other is ValueTuple)) - { - throw new ArgumentException(); - } - - return CompareTo((ValueTuple)other); - } - - /// Compares this instance to a specified instance and returns an indication of their relative values. - /// An instance to compare. - /// - /// A signed number indicating the relative values of this instance and . - /// Returns less than zero if this instance is less than , zero if this - /// instance is equal to , and greater than zero if this instance is greater - /// than . - /// - public int CompareTo(ValueTuple other) - { - int c = Comparer.Default.Compare(Item1, other.Item1); - if (c != 0) return c; - - c = Comparer.Default.Compare(Item2, other.Item2); - if (c != 0) return c; - - c = Comparer.Default.Compare(Item3, other.Item3); - if (c != 0) return c; - - c = Comparer.Default.Compare(Item4, other.Item4); - if (c != 0) return c; - - return Comparer.Default.Compare(Item5, other.Item5); - } - - int IStructuralComparable.CompareTo(object other, IComparer comparer) - { - if (other == null) return 1; - - if (!(other is ValueTuple)) - { - throw new ArgumentException(); - } - - var objTuple = (ValueTuple)other; - - int c = comparer.Compare(Item1, objTuple.Item1); - if (c != 0) return c; - - c = comparer.Compare(Item2, objTuple.Item2); - if (c != 0) return c; - - c = comparer.Compare(Item3, objTuple.Item3); - if (c != 0) return c; - - c = comparer.Compare(Item4, objTuple.Item4); - if (c != 0) return c; - - return comparer.Compare(Item5, objTuple.Item5); - } - - /// - /// Returns the hash code for the current instance. - /// - /// A 32-bit signed integer hash code. - public override int GetHashCode() - { - return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0, - Item2?.GetHashCode() ?? 0, - Item3?.GetHashCode() ?? 0, - Item4?.GetHashCode() ?? 0, - Item5?.GetHashCode() ?? 0); - } - - int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) - { - return GetHashCodeCore(comparer); - } - - private int GetHashCodeCore(IEqualityComparer comparer) - { - return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), - comparer.GetHashCode(Item2), - comparer.GetHashCode(Item3), - comparer.GetHashCode(Item4), - comparer.GetHashCode(Item5)); - } - - int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) - { - return GetHashCodeCore(comparer); - } - - /// - /// Returns a string that represents the value of this instance. - /// - /// The string representation of this instance. - /// - /// The string returned by this method takes the form (Item1, Item2, Item3, Item4, Item5). - /// If any field value is , it is represented as . - /// - public override string ToString() - { - return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ")"; - } - - string IValueTupleInternal.ToStringEnd() - { - return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ")"; - } - - /// - /// The number of positions in this data structure. - /// - int ITuple.Length => 5; - - /// - /// Get the element at position . - /// - object ITuple.this[int index] - { - get - { - switch (index) - { - case 0: - return Item1; - case 1: - return Item2; - case 2: - return Item3; - case 3: - return Item4; - case 4: - return Item5; - default: - throw new IndexOutOfRangeException(); - } - } - } - } - - /// - /// Represents a 6-tuple, or sixtuple, as a value type. - /// - /// The type of the tuple's first component. - /// The type of the tuple's second component. - /// The type of the tuple's third component. - /// The type of the tuple's fourth component. - /// The type of the tuple's fifth component. - /// The type of the tuple's sixth component. - [Serializable] - [StructLayout(LayoutKind.Auto)] - public struct ValueTuple - : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple - { - /// - /// The current instance's first component. - /// - public T1 Item1; - /// - /// The current instance's second component. - /// - public T2 Item2; - /// - /// The current instance's third component. - /// - public T3 Item3; - /// - /// The current instance's fourth component. - /// - public T4 Item4; - /// - /// The current instance's fifth component. - /// - public T5 Item5; - /// - /// The current instance's sixth component. - /// - public T6 Item6; - - /// - /// Initializes a new instance of the value type. - /// - /// The value of the tuple's first component. - /// The value of the tuple's second component. - /// The value of the tuple's third component. - /// The value of the tuple's fourth component. - /// The value of the tuple's fifth component. - /// The value of the tuple's sixth component. - public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) - { - Item1 = item1; - Item2 = item2; - Item3 = item3; - Item4 = item4; - Item5 = item5; - Item6 = item6; - } - - /// - /// Returns a value that indicates whether the current instance is equal to a specified object. - /// - /// The object to compare with this instance. - /// if the current instance is equal to the specified object; otherwise, . - /// - /// The parameter is considered to be equal to the current instance under the following conditions: - /// - /// It is a value type. - /// Its components are of the same types as those of the current instance. - /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. - /// - /// - public override bool Equals(object obj) - { - return obj is ValueTuple && Equals((ValueTuple)obj); - } - - /// - /// Returns a value that indicates whether the current - /// instance is equal to a specified . - /// - /// The tuple to compare with this instance. - /// if the current instance is equal to the specified tuple; otherwise, . - /// - /// The parameter is considered to be equal to the current instance if each of its fields - /// are equal to that of the current instance, using the default comparer for that field's type. - /// - public bool Equals(ValueTuple other) - { - return EqualityComparer.Default.Equals(Item1, other.Item1) - && EqualityComparer.Default.Equals(Item2, other.Item2) - && EqualityComparer.Default.Equals(Item3, other.Item3) - && EqualityComparer.Default.Equals(Item4, other.Item4) - && EqualityComparer.Default.Equals(Item5, other.Item5) - && EqualityComparer.Default.Equals(Item6, other.Item6); - } - - bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) - { - if (other == null || !(other is ValueTuple)) return false; - - var objTuple = (ValueTuple)other; - - return comparer.Equals(Item1, objTuple.Item1) - && comparer.Equals(Item2, objTuple.Item2) - && comparer.Equals(Item3, objTuple.Item3) - && comparer.Equals(Item4, objTuple.Item4) - && comparer.Equals(Item5, objTuple.Item5) - && comparer.Equals(Item6, objTuple.Item6); - } - - int IComparable.CompareTo(object other) - { - if (other == null) return 1; - - if (!(other is ValueTuple)) - { - throw new ArgumentException(); - } - - return CompareTo((ValueTuple)other); - } - - /// Compares this instance to a specified instance and returns an indication of their relative values. - /// An instance to compare. - /// - /// A signed number indicating the relative values of this instance and . - /// Returns less than zero if this instance is less than , zero if this - /// instance is equal to , and greater than zero if this instance is greater - /// than . - /// - public int CompareTo(ValueTuple other) - { - int c = Comparer.Default.Compare(Item1, other.Item1); - if (c != 0) return c; - - c = Comparer.Default.Compare(Item2, other.Item2); - if (c != 0) return c; - - c = Comparer.Default.Compare(Item3, other.Item3); - if (c != 0) return c; - - c = Comparer.Default.Compare(Item4, other.Item4); - if (c != 0) return c; - - c = Comparer.Default.Compare(Item5, other.Item5); - if (c != 0) return c; - - return Comparer.Default.Compare(Item6, other.Item6); - } - - int IStructuralComparable.CompareTo(object other, IComparer comparer) - { - if (other == null) return 1; - - if (!(other is ValueTuple)) - { - throw new ArgumentException(); - } - - var objTuple = (ValueTuple)other; - - int c = comparer.Compare(Item1, objTuple.Item1); - if (c != 0) return c; - - c = comparer.Compare(Item2, objTuple.Item2); - if (c != 0) return c; - - c = comparer.Compare(Item3, objTuple.Item3); - if (c != 0) return c; - - c = comparer.Compare(Item4, objTuple.Item4); - if (c != 0) return c; - - c = comparer.Compare(Item5, objTuple.Item5); - if (c != 0) return c; - - return comparer.Compare(Item6, objTuple.Item6); - } - - /// - /// Returns the hash code for the current instance. - /// - /// A 32-bit signed integer hash code. - public override int GetHashCode() - { - return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0, - Item2?.GetHashCode() ?? 0, - Item3?.GetHashCode() ?? 0, - Item4?.GetHashCode() ?? 0, - Item5?.GetHashCode() ?? 0, - Item6?.GetHashCode() ?? 0); - } - - int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) - { - return GetHashCodeCore(comparer); - } - - private int GetHashCodeCore(IEqualityComparer comparer) - { - return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), - comparer.GetHashCode(Item2), - comparer.GetHashCode(Item3), - comparer.GetHashCode(Item4), - comparer.GetHashCode(Item5), - comparer.GetHashCode(Item6)); - } - - int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) - { - return GetHashCodeCore(comparer); - } - - /// - /// Returns a string that represents the value of this instance. - /// - /// The string representation of this instance. - /// - /// The string returned by this method takes the form (Item1, Item2, Item3, Item4, Item5, Item6). - /// If any field value is , it is represented as . - /// - public override string ToString() - { - return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ")"; - } - - string IValueTupleInternal.ToStringEnd() - { - return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ")"; - } - - /// - /// The number of positions in this data structure. - /// - int ITuple.Length => 6; - - /// - /// Get the element at position . - /// - object ITuple.this[int index] - { - get - { - switch (index) - { - case 0: - return Item1; - case 1: - return Item2; - case 2: - return Item3; - case 3: - return Item4; - case 4: - return Item5; - case 5: - return Item6; - default: - throw new IndexOutOfRangeException(); - } - } - } - } - - /// - /// Represents a 7-tuple, or sentuple, as a value type. - /// - /// The type of the tuple's first component. - /// The type of the tuple's second component. - /// The type of the tuple's third component. - /// The type of the tuple's fourth component. - /// The type of the tuple's fifth component. - /// The type of the tuple's sixth component. - /// The type of the tuple's seventh component. - [Serializable] - [StructLayout(LayoutKind.Auto)] - public struct ValueTuple - : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple - { - /// - /// The current instance's first component. - /// - public T1 Item1; - /// - /// The current instance's second component. - /// - public T2 Item2; - /// - /// The current instance's third component. - /// - public T3 Item3; - /// - /// The current instance's fourth component. - /// - public T4 Item4; - /// - /// The current instance's fifth component. - /// - public T5 Item5; - /// - /// The current instance's sixth component. - /// - public T6 Item6; - /// - /// The current instance's seventh component. - /// - public T7 Item7; - - /// - /// Initializes a new instance of the value type. - /// - /// The value of the tuple's first component. - /// The value of the tuple's second component. - /// The value of the tuple's third component. - /// The value of the tuple's fourth component. - /// The value of the tuple's fifth component. - /// The value of the tuple's sixth component. - /// The value of the tuple's seventh component. - public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) - { - Item1 = item1; - Item2 = item2; - Item3 = item3; - Item4 = item4; - Item5 = item5; - Item6 = item6; - Item7 = item7; - } - - /// - /// Returns a value that indicates whether the current instance is equal to a specified object. - /// - /// The object to compare with this instance. - /// if the current instance is equal to the specified object; otherwise, . - /// - /// The parameter is considered to be equal to the current instance under the following conditions: - /// - /// It is a value type. - /// Its components are of the same types as those of the current instance. - /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. - /// - /// - public override bool Equals(object obj) - { - return obj is ValueTuple && Equals((ValueTuple)obj); - } - - /// - /// Returns a value that indicates whether the current - /// instance is equal to a specified . - /// - /// The tuple to compare with this instance. - /// if the current instance is equal to the specified tuple; otherwise, . - /// - /// The parameter is considered to be equal to the current instance if each of its fields - /// are equal to that of the current instance, using the default comparer for that field's type. - /// - public bool Equals(ValueTuple other) - { - return EqualityComparer.Default.Equals(Item1, other.Item1) - && EqualityComparer.Default.Equals(Item2, other.Item2) - && EqualityComparer.Default.Equals(Item3, other.Item3) - && EqualityComparer.Default.Equals(Item4, other.Item4) - && EqualityComparer.Default.Equals(Item5, other.Item5) - && EqualityComparer.Default.Equals(Item6, other.Item6) - && EqualityComparer.Default.Equals(Item7, other.Item7); - } - - bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) - { - if (other == null || !(other is ValueTuple)) return false; - - var objTuple = (ValueTuple)other; - - return comparer.Equals(Item1, objTuple.Item1) - && comparer.Equals(Item2, objTuple.Item2) - && comparer.Equals(Item3, objTuple.Item3) - && comparer.Equals(Item4, objTuple.Item4) - && comparer.Equals(Item5, objTuple.Item5) - && comparer.Equals(Item6, objTuple.Item6) - && comparer.Equals(Item7, objTuple.Item7); - } - - int IComparable.CompareTo(object other) - { - if (other == null) return 1; - - if (!(other is ValueTuple)) - { - throw new ArgumentException(); - } - - return CompareTo((ValueTuple)other); - } - - /// Compares this instance to a specified instance and returns an indication of their relative values. - /// An instance to compare. - /// - /// A signed number indicating the relative values of this instance and . - /// Returns less than zero if this instance is less than , zero if this - /// instance is equal to , and greater than zero if this instance is greater - /// than . - /// - public int CompareTo(ValueTuple other) - { - int c = Comparer.Default.Compare(Item1, other.Item1); - if (c != 0) return c; - - c = Comparer.Default.Compare(Item2, other.Item2); - if (c != 0) return c; - - c = Comparer.Default.Compare(Item3, other.Item3); - if (c != 0) return c; - - c = Comparer.Default.Compare(Item4, other.Item4); - if (c != 0) return c; - - c = Comparer.Default.Compare(Item5, other.Item5); - if (c != 0) return c; - - c = Comparer.Default.Compare(Item6, other.Item6); - if (c != 0) return c; - - return Comparer.Default.Compare(Item7, other.Item7); - } - - int IStructuralComparable.CompareTo(object other, IComparer comparer) - { - if (other == null) return 1; - - if (!(other is ValueTuple)) - { - throw new ArgumentException(); - } - - var objTuple = (ValueTuple)other; - - int c = comparer.Compare(Item1, objTuple.Item1); - if (c != 0) return c; - - c = comparer.Compare(Item2, objTuple.Item2); - if (c != 0) return c; - - c = comparer.Compare(Item3, objTuple.Item3); - if (c != 0) return c; - - c = comparer.Compare(Item4, objTuple.Item4); - if (c != 0) return c; - - c = comparer.Compare(Item5, objTuple.Item5); - if (c != 0) return c; - - c = comparer.Compare(Item6, objTuple.Item6); - if (c != 0) return c; - - return comparer.Compare(Item7, objTuple.Item7); - } - - /// - /// Returns the hash code for the current instance. - /// - /// A 32-bit signed integer hash code. - public override int GetHashCode() - { - return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0, - Item2?.GetHashCode() ?? 0, - Item3?.GetHashCode() ?? 0, - Item4?.GetHashCode() ?? 0, - Item5?.GetHashCode() ?? 0, - Item6?.GetHashCode() ?? 0, - Item7?.GetHashCode() ?? 0); - } - - int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) - { - return GetHashCodeCore(comparer); - } - - private int GetHashCodeCore(IEqualityComparer comparer) - { - return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), - comparer.GetHashCode(Item2), - comparer.GetHashCode(Item3), - comparer.GetHashCode(Item4), - comparer.GetHashCode(Item5), - comparer.GetHashCode(Item6), - comparer.GetHashCode(Item7)); - } - - int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) - { - return GetHashCodeCore(comparer); - } - - /// - /// Returns a string that represents the value of this instance. - /// - /// The string representation of this instance. - /// - /// The string returned by this method takes the form (Item1, Item2, Item3, Item4, Item5, Item6, Item7). - /// If any field value is , it is represented as . - /// - public override string ToString() - { - return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ")"; - } - - string IValueTupleInternal.ToStringEnd() - { - return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ")"; - } - - /// - /// The number of positions in this data structure. - /// - int ITuple.Length => 7; - - /// - /// Get the element at position . - /// - object ITuple.this[int index] - { - get - { - switch (index) - { - case 0: - return Item1; - case 1: - return Item2; - case 2: - return Item3; - case 3: - return Item4; - case 4: - return Item5; - case 5: - return Item6; - case 6: - return Item7; - default: - throw new IndexOutOfRangeException(); - } - } - } - } - - /// - /// Represents an 8-tuple, or octuple, as a value type. - /// - /// The type of the tuple's first component. - /// The type of the tuple's second component. - /// The type of the tuple's third component. - /// The type of the tuple's fourth component. - /// The type of the tuple's fifth component. - /// The type of the tuple's sixth component. - /// The type of the tuple's seventh component. - /// The type of the tuple's eighth component. - [Serializable] - [StructLayout(LayoutKind.Auto)] - public struct ValueTuple - : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple - where TRest : struct - { - /// - /// The current instance's first component. - /// - public T1 Item1; - /// - /// The current instance's second component. - /// - public T2 Item2; - /// - /// The current instance's third component. - /// - public T3 Item3; - /// - /// The current instance's fourth component. - /// - public T4 Item4; - /// - /// The current instance's fifth component. - /// - public T5 Item5; - /// - /// The current instance's sixth component. - /// - public T6 Item6; - /// - /// The current instance's seventh component. - /// - public T7 Item7; - /// - /// The current instance's eighth component. - /// - public TRest Rest; - - /// - /// Initializes a new instance of the value type. - /// - /// The value of the tuple's first component. - /// The value of the tuple's second component. - /// The value of the tuple's third component. - /// The value of the tuple's fourth component. - /// The value of the tuple's fifth component. - /// The value of the tuple's sixth component. - /// The value of the tuple's seventh component. - /// The value of the tuple's eight component. - public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) - { - if (!(rest is IValueTupleInternal)) - { - throw new ArgumentException(); - } - - Item1 = item1; - Item2 = item2; - Item3 = item3; - Item4 = item4; - Item5 = item5; - Item6 = item6; - Item7 = item7; - Rest = rest; - } - - /// - /// Returns a value that indicates whether the current instance is equal to a specified object. - /// - /// The object to compare with this instance. - /// if the current instance is equal to the specified object; otherwise, . - /// - /// The parameter is considered to be equal to the current instance under the following conditions: - /// - /// It is a value type. - /// Its components are of the same types as those of the current instance. - /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. - /// - /// - public override bool Equals(object obj) - { - return obj is ValueTuple && Equals((ValueTuple)obj); - } - - /// - /// Returns a value that indicates whether the current - /// instance is equal to a specified . - /// - /// The tuple to compare with this instance. - /// if the current instance is equal to the specified tuple; otherwise, . - /// - /// The parameter is considered to be equal to the current instance if each of its fields - /// are equal to that of the current instance, using the default comparer for that field's type. - /// - public bool Equals(ValueTuple other) - { - return EqualityComparer.Default.Equals(Item1, other.Item1) - && EqualityComparer.Default.Equals(Item2, other.Item2) - && EqualityComparer.Default.Equals(Item3, other.Item3) - && EqualityComparer.Default.Equals(Item4, other.Item4) - && EqualityComparer.Default.Equals(Item5, other.Item5) - && EqualityComparer.Default.Equals(Item6, other.Item6) - && EqualityComparer.Default.Equals(Item7, other.Item7) - && EqualityComparer.Default.Equals(Rest, other.Rest); - } - - bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) - { - if (other == null || !(other is ValueTuple)) return false; - - var objTuple = (ValueTuple)other; - - return comparer.Equals(Item1, objTuple.Item1) - && comparer.Equals(Item2, objTuple.Item2) - && comparer.Equals(Item3, objTuple.Item3) - && comparer.Equals(Item4, objTuple.Item4) - && comparer.Equals(Item5, objTuple.Item5) - && comparer.Equals(Item6, objTuple.Item6) - && comparer.Equals(Item7, objTuple.Item7) - && comparer.Equals(Rest, objTuple.Rest); - } - - int IComparable.CompareTo(object other) - { - if (other == null) return 1; - - if (!(other is ValueTuple)) - { - throw new ArgumentException(); - } - - return CompareTo((ValueTuple)other); - } - - /// Compares this instance to a specified instance and returns an indication of their relative values. - /// An instance to compare. - /// - /// A signed number indicating the relative values of this instance and . - /// Returns less than zero if this instance is less than , zero if this - /// instance is equal to , and greater than zero if this instance is greater - /// than . - /// - public int CompareTo(ValueTuple other) - { - int c = Comparer.Default.Compare(Item1, other.Item1); - if (c != 0) return c; - - c = Comparer.Default.Compare(Item2, other.Item2); - if (c != 0) return c; - - c = Comparer.Default.Compare(Item3, other.Item3); - if (c != 0) return c; - - c = Comparer.Default.Compare(Item4, other.Item4); - if (c != 0) return c; - - c = Comparer.Default.Compare(Item5, other.Item5); - if (c != 0) return c; - - c = Comparer.Default.Compare(Item6, other.Item6); - if (c != 0) return c; - - c = Comparer.Default.Compare(Item7, other.Item7); - if (c != 0) return c; - - return Comparer.Default.Compare(Rest, other.Rest); - } - - int IStructuralComparable.CompareTo(object other, IComparer comparer) - { - if (other == null) return 1; - - if (!(other is ValueTuple)) - { - throw new ArgumentException(); - } - - var objTuple = (ValueTuple)other; - - int c = comparer.Compare(Item1, objTuple.Item1); - if (c != 0) return c; - - c = comparer.Compare(Item2, objTuple.Item2); - if (c != 0) return c; - - c = comparer.Compare(Item3, objTuple.Item3); - if (c != 0) return c; - - c = comparer.Compare(Item4, objTuple.Item4); - if (c != 0) return c; - - c = comparer.Compare(Item5, objTuple.Item5); - if (c != 0) return c; - - c = comparer.Compare(Item6, objTuple.Item6); - if (c != 0) return c; - - c = comparer.Compare(Item7, objTuple.Item7); - if (c != 0) return c; - - return comparer.Compare(Rest, objTuple.Rest); - } - - /// - /// Returns the hash code for the current instance. - /// - /// A 32-bit signed integer hash code. - public override int GetHashCode() - { - // We want to have a limited hash in this case. We'll use the last 8 elements of the tuple - IValueTupleInternal rest = Rest as IValueTupleInternal; - if (rest == null) - { - return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0, - Item2?.GetHashCode() ?? 0, - Item3?.GetHashCode() ?? 0, - Item4?.GetHashCode() ?? 0, - Item5?.GetHashCode() ?? 0, - Item6?.GetHashCode() ?? 0, - Item7?.GetHashCode() ?? 0); - } - - int size = rest.Length; - if (size >= 8) { return rest.GetHashCode(); } - - // In this case, the rest member has less than 8 elements so we need to combine some our elements with the elements in rest - int k = 8 - size; - switch (k) - { - case 1: - return ValueTuple.CombineHashCodes(Item7?.GetHashCode() ?? 0, - rest.GetHashCode()); - case 2: - return ValueTuple.CombineHashCodes(Item6?.GetHashCode() ?? 0, - Item7?.GetHashCode() ?? 0, - rest.GetHashCode()); - case 3: - return ValueTuple.CombineHashCodes(Item5?.GetHashCode() ?? 0, - Item6?.GetHashCode() ?? 0, - Item7?.GetHashCode() ?? 0, - rest.GetHashCode()); - case 4: - return ValueTuple.CombineHashCodes(Item4?.GetHashCode() ?? 0, - Item5?.GetHashCode() ?? 0, - Item6?.GetHashCode() ?? 0, - Item7?.GetHashCode() ?? 0, - rest.GetHashCode()); - case 5: - return ValueTuple.CombineHashCodes(Item3?.GetHashCode() ?? 0, - Item4?.GetHashCode() ?? 0, - Item5?.GetHashCode() ?? 0, - Item6?.GetHashCode() ?? 0, - Item7?.GetHashCode() ?? 0, - rest.GetHashCode()); - case 6: - return ValueTuple.CombineHashCodes(Item2?.GetHashCode() ?? 0, - Item3?.GetHashCode() ?? 0, - Item4?.GetHashCode() ?? 0, - Item5?.GetHashCode() ?? 0, - Item6?.GetHashCode() ?? 0, - Item7?.GetHashCode() ?? 0, - rest.GetHashCode()); - case 7: - case 8: - return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0, - Item2?.GetHashCode() ?? 0, - Item3?.GetHashCode() ?? 0, - Item4?.GetHashCode() ?? 0, - Item5?.GetHashCode() ?? 0, - Item6?.GetHashCode() ?? 0, - Item7?.GetHashCode() ?? 0, - rest.GetHashCode()); - } - - Contract.Assert(false, "Missed all cases for computing ValueTuple hash code"); - return -1; - } - - int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) - { - return GetHashCodeCore(comparer); - } - - private int GetHashCodeCore(IEqualityComparer comparer) - { - // We want to have a limited hash in this case. We'll use the last 8 elements of the tuple - IValueTupleInternal rest = Rest as IValueTupleInternal; - if (rest == null) - { - return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), - comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), - comparer.GetHashCode(Item7)); - } - - int size = rest.Length; - if (size >= 8) { return rest.GetHashCode(comparer); } - - // In this case, the rest member has less than 8 elements so we need to combine some our elements with the elements in rest - int k = 8 - size; - switch (k) - { - case 1: - return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item7), rest.GetHashCode(comparer)); - case 2: - return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), rest.GetHashCode(comparer)); - case 3: - return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), - rest.GetHashCode(comparer)); - case 4: - return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), - comparer.GetHashCode(Item7), rest.GetHashCode(comparer)); - case 5: - return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), - comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), rest.GetHashCode(comparer)); - case 6: - return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), - comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), - rest.GetHashCode(comparer)); - case 7: - case 8: - return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), - comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), - comparer.GetHashCode(Item7), rest.GetHashCode(comparer)); - } - - Contract.Assert(false, "Missed all cases for computing ValueTuple hash code"); - return -1; - } - - int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) - { - return GetHashCodeCore(comparer); - } - - /// - /// Returns a string that represents the value of this instance. - /// - /// The string representation of this instance. - /// - /// The string returned by this method takes the form (Item1, Item2, Item3, Item4, Item5, Item6, Item7, Rest). - /// If any field value is , it is represented as . - /// - public override string ToString() - { - IValueTupleInternal rest = Rest as IValueTupleInternal; - if (rest == null) - { - return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + Rest.ToString() + ")"; - } - else - { - return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + rest.ToStringEnd(); - } - } - - string IValueTupleInternal.ToStringEnd() - { - IValueTupleInternal rest = Rest as IValueTupleInternal; - if (rest == null) - { - return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + Rest.ToString() + ")"; - } - else - { - return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + rest.ToStringEnd(); - } - } - - /// - /// The number of positions in this data structure. - /// - int ITuple.Length - { - get - { - IValueTupleInternal rest = Rest as IValueTupleInternal; - return rest == null ? 8 : 7 + rest.Length; - } - } - - /// - /// Get the element at position . - /// - object ITuple.this[int index] - { - get - { - switch (index) - { - case 0: - return Item1; - case 1: - return Item2; - case 2: - return Item3; - case 3: - return Item4; - case 4: - return Item5; - case 5: - return Item6; - case 6: - return Item7; - } - - IValueTupleInternal rest = Rest as IValueTupleInternal; - if (rest == null) - { - if (index == 7) - { - return Rest; - } - throw new IndexOutOfRangeException(); - } - return rest[index - 7]; - } - } - } -} -#endif From 4ddeff5e9c1fd7c26366f5a11e1b88cde87f774d Mon Sep 17 00:00:00 2001 From: walterlv Date: Sat, 27 Apr 2024 16:09:06 +0800 Subject: [PATCH 22/23] =?UTF-8?q?=E5=9B=A0=E4=B8=BA=E5=B7=B2=E7=BB=8F?= =?UTF-8?q?=E4=B8=8D=E5=AD=98=E5=9C=A8=20ValueTuple=EF=BC=8C=E6=89=80?= =?UTF-8?q?=E4=BB=A5=E6=97=A0=E9=9C=80=E7=94=9F=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FeatureGenerator.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/dotnetCampus.LatestCSharpFeatures.Analyzer/FeatureGenerator.cs b/src/dotnetCampus.LatestCSharpFeatures.Analyzer/FeatureGenerator.cs index 99a2468..40f2fff 100644 --- a/src/dotnetCampus.LatestCSharpFeatures.Analyzer/FeatureGenerator.cs +++ b/src/dotnetCampus.LatestCSharpFeatures.Analyzer/FeatureGenerator.cs @@ -1,4 +1,4 @@ -using dotnetCampus.LatestCSharpFeatures.Analyzer; +using dotnetCampus.LatestCSharpFeatures.Analyzer; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; @@ -19,9 +19,6 @@ public void Initialize(IncrementalGeneratorInitializationContext context) private void OnExecute(SourceProductionContext context, AnalyzerConfigOptionsProvider provider) { - // .NET Core 1.0 / .NET Framework 4.7 / .NET Standard 2.0 才开始支持 ValueTuple。 - GenerateFeatureSource(context, provider, "ValueTuple"); - // .NET Core 3.0 / .NET Standard 2.1 才开始支持 Nullable;.NET 5.0 开始支持更多。 GenerateFeatureSource(context, provider, "Nullable"); From d17befe9ce2876dd4530ca117a0c4a78a3089f91 Mon Sep 17 00:00:00 2001 From: walterlv Date: Sun, 28 Apr 2024 09:50:52 +0800 Subject: [PATCH 23/23] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=A2=84=E8=A7=88?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dotnetCampus.LatestCSharpFeatures.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/dotnetCampus.LatestCSharpFeatures.Tests/dotnetCampus.LatestCSharpFeatures.Tests.csproj b/tests/dotnetCampus.LatestCSharpFeatures.Tests/dotnetCampus.LatestCSharpFeatures.Tests.csproj index bec72bd..e343a95 100644 --- a/tests/dotnetCampus.LatestCSharpFeatures.Tests/dotnetCampus.LatestCSharpFeatures.Tests.csproj +++ b/tests/dotnetCampus.LatestCSharpFeatures.Tests/dotnetCampus.LatestCSharpFeatures.Tests.csproj @@ -17,7 +17,7 @@ - +