├── .editorconfig ├── .gitattributes ├── .gitignore ├── .travis.yml ├── LICENSE ├── NetLegacySupport.sln ├── NetLegacySupport.snk ├── README.md ├── appveyor.yml ├── build.cmd ├── build.fsx ├── core ├── Action.Net20.Tests │ ├── Action.Net20.Tests.csproj │ ├── Properties │ │ └── AssemblyInfo.cs │ └── packages.config ├── Action.Net20 │ └── Action.Net20.csproj ├── Action.Net35.Tests │ ├── Action.Net35.Tests.csproj │ ├── Properties │ │ └── AssemblyInfo.cs │ └── packages.config ├── Action.Net35 │ └── Action.Net35.csproj ├── Action.Net40.Tests │ ├── Action.Net40.Tests.csproj │ ├── Properties │ │ └── AssemblyInfo.cs │ └── packages.config ├── Action.Net40 │ └── Action.Net40.csproj ├── Action.Tests │ └── TestAction.cs ├── Action │ ├── NetLegacySupport.Action.Release.md │ ├── NetLegacySupport.Action.nuspec │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ └── AssemblyInfoGenerated.cs │ └── System │ │ └── Action.cs ├── ConcurrentDictionary.Net20.Tests │ ├── ConcurrentDictionary.Net20.Tests.csproj │ ├── Properties │ │ └── AssemblyInfo.cs │ └── packages.config ├── ConcurrentDictionary.Net20 │ └── ConcurrentDictionary.Net20.csproj ├── ConcurrentDictionary.Net35.Tests │ ├── ConcurrentDictionary.Net35.Tests.csproj │ ├── Properties │ │ └── AssemblyInfo.cs │ └── packages.config ├── ConcurrentDictionary.Net35 │ └── ConcurrentDictionary.Net35.csproj ├── ConcurrentDictionary.Net40.Tests │ ├── ConcurrentDictionary.Net40.Tests.csproj │ ├── Properties │ │ └── AssemblyInfo.cs │ └── packages.config ├── ConcurrentDictionary.Net40 │ └── ConcurrentDictionary.Net40.csproj ├── ConcurrentDictionary.Tests │ └── ConcurrentDictionaryTests.cs ├── ConcurrentDictionary │ ├── NetLegacySupport.ConcurrentDictionary.Release.md │ ├── NetLegacySupport.ConcurrentDictionary.nuspec │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ └── AssemblyInfoGenerated.cs │ └── System │ │ └── Collections │ │ └── Concurrent │ │ ├── ConcurrentDictionary.cs │ │ └── FrameworkTraits.cs ├── Tuple.Net20.Tests │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Tuple.Net20.Tests.csproj │ └── packages.config ├── Tuple.Net20 │ └── Tuple.Net20.csproj ├── Tuple.Net35.Tests │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Tuple.Net35.Tests.csproj │ └── packages.config ├── Tuple.Net35 │ └── Tuple.Net35.csproj ├── Tuple.Net40.Tests │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Tuple.Net40.Tests.csproj │ └── packages.config ├── Tuple.Net40 │ └── Tuple.Net40.csproj ├── Tuple.Tests │ └── TestTuple.cs ├── Tuple │ ├── NetLegacySupport.Tuple.Release.md │ ├── NetLegacySupport.Tuple.nuspec │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ └── AssemblyInfoGenerated.cs │ └── System │ │ ├── Collections │ │ ├── IStructuralComparable.cs │ │ └── IStructuralEquatable.cs │ │ └── Tuple.cs └── UnityPackage │ └── NetLegacySupport.unitypackage.json └── tools └── nuget ├── NuGet.Config ├── NuGet.targets ├── nuget.exe └── packages.config /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*.{cs, py, fsx}] 4 | indent_style = space 5 | indent_size = 4 6 | trim_trailing_whitespace = true 7 | insert_final_newline = true 8 | 9 | [*.{json, xml}] 10 | indent_style = space 11 | indent_size = 2 12 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # User-specific files 2 | *.suo 3 | *.user 4 | *.userosscache 5 | *.sln.docstates 6 | 7 | # Build results 8 | [Dd]ebug/ 9 | [Dd]ebugPublic/ 10 | [Rr]elease/ 11 | [Rr]eleases/ 12 | x64/ 13 | x86/ 14 | build/ 15 | bld/ 16 | [Bb]in/ 17 | [Oo]bj/ 18 | 19 | # Coverity output 20 | cov-int/ 21 | 22 | # Visual Studio 2015 cache/options directory 23 | .vs/ 24 | 25 | # DNX 26 | project.lock.json 27 | artifacts/ 28 | 29 | # Visual Studio profiler 30 | *.psess 31 | *.vsp 32 | *.vspx 33 | 34 | # Visual Studio Code 35 | .vscode 36 | 37 | # Click-Once directory 38 | [Pp]ublish/ 39 | 40 | # NuGet Packages 41 | *.nupkg 42 | # The packages folder can be ignored because of Package Restore 43 | **/packages/* 44 | # except build/, which is used as an MSBuild target. 45 | !**/packages/build/ 46 | # Uncomment if necessary however generally it will be regenerated when needed 47 | #!**/packages/repositories.config 48 | 49 | # Windows Azure Build Output 50 | csx/ 51 | *.build.csdef 52 | 53 | # Windows Store app package directory 54 | AppPackages/ 55 | 56 | # Visual Studio cache files 57 | # files ending in .cache can be ignored 58 | *.[Cc]ache 59 | # but keep track of directories ending in .cache 60 | !*.[Cc]ache/ 61 | 62 | # Fake 63 | .fake/ 64 | 65 | # No APK 66 | *.apk 67 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: csharp 2 | solution: NetLegacySupport.sln 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 SaladLab 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /NetLegacySupport.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.24720.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Action", "Action", "{FEC4E277-A360-4E60-B2C2-21DD96E92770}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Action.Net40", "core\Action.Net40\Action.Net40.csproj", "{8E41D66F-AACC-4D7C-8766-DFD20704A3D2}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Action.Net40.Tests", "core\Action.Net40.Tests\Action.Net40.Tests.csproj", "{828C75BE-363B-4DD9-951C-43660B3BCB8B}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Action.Net20", "core\Action.Net20\Action.Net20.csproj", "{F1CBA647-CA9E-40D6-B54F-E14F7205AC15}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Action.Net20.Tests", "core\Action.Net20.Tests\Action.Net20.Tests.csproj", "{ADFB6063-D389-4E26-9A82-A57D6AF1811E}" 15 | EndProject 16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Action.Net35", "core\Action.Net35\Action.Net35.csproj", "{2E4CC3AC-0F6E-4FFA-A6E4-722AE7F5D04D}" 17 | EndProject 18 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Action.Net35.Tests", "core\Action.Net35.Tests\Action.Net35.Tests.csproj", "{DCD8CA2C-5675-4F71-9C45-A1C3D463944A}" 19 | EndProject 20 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ConcurrentDictionary", "ConcurrentDictionary", "{61C48C0C-34E9-44B0-B9EA-2033E96FA298}" 21 | EndProject 22 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tuple", "Tuple", "{CC594387-4476-425D-9E5A-07FD824D1719}" 23 | EndProject 24 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConcurrentDictionary.Net20", "core\ConcurrentDictionary.Net20\ConcurrentDictionary.Net20.csproj", "{F4E37673-D6CC-4320-8AA6-67234E0034C6}" 25 | EndProject 26 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConcurrentDictionary.Net20.Tests", "core\ConcurrentDictionary.Net20.Tests\ConcurrentDictionary.Net20.Tests.csproj", "{AEDDF472-2B32-4360-9E91-885B00D692DF}" 27 | EndProject 28 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tuple.Net20", "core\Tuple.Net20\Tuple.Net20.csproj", "{5545B95D-C742-4C8B-8A4D-70B548050547}" 29 | EndProject 30 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tuple.Net20.Tests", "core\Tuple.Net20.Tests\Tuple.Net20.Tests.csproj", "{15522D4F-0A13-4AE1-94B8-AE99B0D0847E}" 31 | EndProject 32 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConcurrentDictionary.Net35", "core\ConcurrentDictionary.Net35\ConcurrentDictionary.Net35.csproj", "{381252A5-912B-4B99-B429-8D1029569491}" 33 | EndProject 34 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConcurrentDictionary.Net35.Tests", "core\ConcurrentDictionary.Net35.Tests\ConcurrentDictionary.Net35.Tests.csproj", "{942F561E-74D3-44A6-99FA-72D3AC288313}" 35 | EndProject 36 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConcurrentDictionary.Net40", "core\ConcurrentDictionary.Net40\ConcurrentDictionary.Net40.csproj", "{26525F44-B7A6-4DA1-8283-A47C4440D8AB}" 37 | EndProject 38 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConcurrentDictionary.Net40.Tests", "core\ConcurrentDictionary.Net40.Tests\ConcurrentDictionary.Net40.Tests.csproj", "{0CC64432-4BBC-426D-BED8-52963DD3C67D}" 39 | EndProject 40 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tuple.Net35", "core\Tuple.Net35\Tuple.Net35.csproj", "{D434BDDD-1EDA-4212-B6D6-52DD80A08969}" 41 | EndProject 42 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tuple.Net35.Tests", "core\Tuple.Net35.Tests\Tuple.Net35.Tests.csproj", "{461A55B6-5DB1-44C3-BD71-D286A356C0A8}" 43 | EndProject 44 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tuple.Net40", "core\Tuple.Net40\Tuple.Net40.csproj", "{DF53F862-9220-4C36-9973-B7E899EA4596}" 45 | EndProject 46 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tuple.Net40.Tests", "core\Tuple.Net40.Tests\Tuple.Net40.Tests.csproj", "{10BEF5B7-7F3F-4A5C-8B43-B1F2C6637AF9}" 47 | EndProject 48 | Global 49 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 50 | Debug|Any CPU = Debug|Any CPU 51 | Release|Any CPU = Release|Any CPU 52 | EndGlobalSection 53 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 54 | {8E41D66F-AACC-4D7C-8766-DFD20704A3D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 55 | {8E41D66F-AACC-4D7C-8766-DFD20704A3D2}.Debug|Any CPU.Build.0 = Debug|Any CPU 56 | {8E41D66F-AACC-4D7C-8766-DFD20704A3D2}.Release|Any CPU.ActiveCfg = Release|Any CPU 57 | {8E41D66F-AACC-4D7C-8766-DFD20704A3D2}.Release|Any CPU.Build.0 = Release|Any CPU 58 | {828C75BE-363B-4DD9-951C-43660B3BCB8B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 59 | {828C75BE-363B-4DD9-951C-43660B3BCB8B}.Debug|Any CPU.Build.0 = Debug|Any CPU 60 | {828C75BE-363B-4DD9-951C-43660B3BCB8B}.Release|Any CPU.ActiveCfg = Release|Any CPU 61 | {828C75BE-363B-4DD9-951C-43660B3BCB8B}.Release|Any CPU.Build.0 = Release|Any CPU 62 | {F1CBA647-CA9E-40D6-B54F-E14F7205AC15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 63 | {F1CBA647-CA9E-40D6-B54F-E14F7205AC15}.Debug|Any CPU.Build.0 = Debug|Any CPU 64 | {F1CBA647-CA9E-40D6-B54F-E14F7205AC15}.Release|Any CPU.ActiveCfg = Release|Any CPU 65 | {F1CBA647-CA9E-40D6-B54F-E14F7205AC15}.Release|Any CPU.Build.0 = Release|Any CPU 66 | {ADFB6063-D389-4E26-9A82-A57D6AF1811E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 67 | {ADFB6063-D389-4E26-9A82-A57D6AF1811E}.Debug|Any CPU.Build.0 = Debug|Any CPU 68 | {ADFB6063-D389-4E26-9A82-A57D6AF1811E}.Release|Any CPU.ActiveCfg = Release|Any CPU 69 | {ADFB6063-D389-4E26-9A82-A57D6AF1811E}.Release|Any CPU.Build.0 = Release|Any CPU 70 | {2E4CC3AC-0F6E-4FFA-A6E4-722AE7F5D04D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 71 | {2E4CC3AC-0F6E-4FFA-A6E4-722AE7F5D04D}.Debug|Any CPU.Build.0 = Debug|Any CPU 72 | {2E4CC3AC-0F6E-4FFA-A6E4-722AE7F5D04D}.Release|Any CPU.ActiveCfg = Release|Any CPU 73 | {2E4CC3AC-0F6E-4FFA-A6E4-722AE7F5D04D}.Release|Any CPU.Build.0 = Release|Any CPU 74 | {DCD8CA2C-5675-4F71-9C45-A1C3D463944A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 75 | {DCD8CA2C-5675-4F71-9C45-A1C3D463944A}.Debug|Any CPU.Build.0 = Debug|Any CPU 76 | {DCD8CA2C-5675-4F71-9C45-A1C3D463944A}.Release|Any CPU.ActiveCfg = Release|Any CPU 77 | {DCD8CA2C-5675-4F71-9C45-A1C3D463944A}.Release|Any CPU.Build.0 = Release|Any CPU 78 | {F4E37673-D6CC-4320-8AA6-67234E0034C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 79 | {F4E37673-D6CC-4320-8AA6-67234E0034C6}.Debug|Any CPU.Build.0 = Debug|Any CPU 80 | {F4E37673-D6CC-4320-8AA6-67234E0034C6}.Release|Any CPU.ActiveCfg = Release|Any CPU 81 | {F4E37673-D6CC-4320-8AA6-67234E0034C6}.Release|Any CPU.Build.0 = Release|Any CPU 82 | {AEDDF472-2B32-4360-9E91-885B00D692DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 83 | {AEDDF472-2B32-4360-9E91-885B00D692DF}.Debug|Any CPU.Build.0 = Debug|Any CPU 84 | {AEDDF472-2B32-4360-9E91-885B00D692DF}.Release|Any CPU.ActiveCfg = Release|Any CPU 85 | {AEDDF472-2B32-4360-9E91-885B00D692DF}.Release|Any CPU.Build.0 = Release|Any CPU 86 | {5545B95D-C742-4C8B-8A4D-70B548050547}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 87 | {5545B95D-C742-4C8B-8A4D-70B548050547}.Debug|Any CPU.Build.0 = Debug|Any CPU 88 | {5545B95D-C742-4C8B-8A4D-70B548050547}.Release|Any CPU.ActiveCfg = Release|Any CPU 89 | {5545B95D-C742-4C8B-8A4D-70B548050547}.Release|Any CPU.Build.0 = Release|Any CPU 90 | {15522D4F-0A13-4AE1-94B8-AE99B0D0847E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 91 | {15522D4F-0A13-4AE1-94B8-AE99B0D0847E}.Debug|Any CPU.Build.0 = Debug|Any CPU 92 | {15522D4F-0A13-4AE1-94B8-AE99B0D0847E}.Release|Any CPU.ActiveCfg = Release|Any CPU 93 | {15522D4F-0A13-4AE1-94B8-AE99B0D0847E}.Release|Any CPU.Build.0 = Release|Any CPU 94 | {381252A5-912B-4B99-B429-8D1029569491}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 95 | {381252A5-912B-4B99-B429-8D1029569491}.Debug|Any CPU.Build.0 = Debug|Any CPU 96 | {381252A5-912B-4B99-B429-8D1029569491}.Release|Any CPU.ActiveCfg = Release|Any CPU 97 | {381252A5-912B-4B99-B429-8D1029569491}.Release|Any CPU.Build.0 = Release|Any CPU 98 | {942F561E-74D3-44A6-99FA-72D3AC288313}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 99 | {942F561E-74D3-44A6-99FA-72D3AC288313}.Debug|Any CPU.Build.0 = Debug|Any CPU 100 | {942F561E-74D3-44A6-99FA-72D3AC288313}.Release|Any CPU.ActiveCfg = Release|Any CPU 101 | {942F561E-74D3-44A6-99FA-72D3AC288313}.Release|Any CPU.Build.0 = Release|Any CPU 102 | {26525F44-B7A6-4DA1-8283-A47C4440D8AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 103 | {26525F44-B7A6-4DA1-8283-A47C4440D8AB}.Debug|Any CPU.Build.0 = Debug|Any CPU 104 | {26525F44-B7A6-4DA1-8283-A47C4440D8AB}.Release|Any CPU.ActiveCfg = Release|Any CPU 105 | {26525F44-B7A6-4DA1-8283-A47C4440D8AB}.Release|Any CPU.Build.0 = Release|Any CPU 106 | {0CC64432-4BBC-426D-BED8-52963DD3C67D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 107 | {0CC64432-4BBC-426D-BED8-52963DD3C67D}.Debug|Any CPU.Build.0 = Debug|Any CPU 108 | {0CC64432-4BBC-426D-BED8-52963DD3C67D}.Release|Any CPU.ActiveCfg = Release|Any CPU 109 | {0CC64432-4BBC-426D-BED8-52963DD3C67D}.Release|Any CPU.Build.0 = Release|Any CPU 110 | {D434BDDD-1EDA-4212-B6D6-52DD80A08969}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 111 | {D434BDDD-1EDA-4212-B6D6-52DD80A08969}.Debug|Any CPU.Build.0 = Debug|Any CPU 112 | {D434BDDD-1EDA-4212-B6D6-52DD80A08969}.Release|Any CPU.ActiveCfg = Release|Any CPU 113 | {D434BDDD-1EDA-4212-B6D6-52DD80A08969}.Release|Any CPU.Build.0 = Release|Any CPU 114 | {461A55B6-5DB1-44C3-BD71-D286A356C0A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 115 | {461A55B6-5DB1-44C3-BD71-D286A356C0A8}.Debug|Any CPU.Build.0 = Debug|Any CPU 116 | {461A55B6-5DB1-44C3-BD71-D286A356C0A8}.Release|Any CPU.ActiveCfg = Release|Any CPU 117 | {461A55B6-5DB1-44C3-BD71-D286A356C0A8}.Release|Any CPU.Build.0 = Release|Any CPU 118 | {DF53F862-9220-4C36-9973-B7E899EA4596}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 119 | {DF53F862-9220-4C36-9973-B7E899EA4596}.Debug|Any CPU.Build.0 = Debug|Any CPU 120 | {DF53F862-9220-4C36-9973-B7E899EA4596}.Release|Any CPU.ActiveCfg = Release|Any CPU 121 | {DF53F862-9220-4C36-9973-B7E899EA4596}.Release|Any CPU.Build.0 = Release|Any CPU 122 | {10BEF5B7-7F3F-4A5C-8B43-B1F2C6637AF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 123 | {10BEF5B7-7F3F-4A5C-8B43-B1F2C6637AF9}.Debug|Any CPU.Build.0 = Debug|Any CPU 124 | {10BEF5B7-7F3F-4A5C-8B43-B1F2C6637AF9}.Release|Any CPU.ActiveCfg = Release|Any CPU 125 | {10BEF5B7-7F3F-4A5C-8B43-B1F2C6637AF9}.Release|Any CPU.Build.0 = Release|Any CPU 126 | EndGlobalSection 127 | GlobalSection(SolutionProperties) = preSolution 128 | HideSolutionNode = FALSE 129 | EndGlobalSection 130 | GlobalSection(NestedProjects) = preSolution 131 | {8E41D66F-AACC-4D7C-8766-DFD20704A3D2} = {FEC4E277-A360-4E60-B2C2-21DD96E92770} 132 | {828C75BE-363B-4DD9-951C-43660B3BCB8B} = {FEC4E277-A360-4E60-B2C2-21DD96E92770} 133 | {F1CBA647-CA9E-40D6-B54F-E14F7205AC15} = {FEC4E277-A360-4E60-B2C2-21DD96E92770} 134 | {ADFB6063-D389-4E26-9A82-A57D6AF1811E} = {FEC4E277-A360-4E60-B2C2-21DD96E92770} 135 | {2E4CC3AC-0F6E-4FFA-A6E4-722AE7F5D04D} = {FEC4E277-A360-4E60-B2C2-21DD96E92770} 136 | {DCD8CA2C-5675-4F71-9C45-A1C3D463944A} = {FEC4E277-A360-4E60-B2C2-21DD96E92770} 137 | {F4E37673-D6CC-4320-8AA6-67234E0034C6} = {61C48C0C-34E9-44B0-B9EA-2033E96FA298} 138 | {AEDDF472-2B32-4360-9E91-885B00D692DF} = {61C48C0C-34E9-44B0-B9EA-2033E96FA298} 139 | {5545B95D-C742-4C8B-8A4D-70B548050547} = {CC594387-4476-425D-9E5A-07FD824D1719} 140 | {15522D4F-0A13-4AE1-94B8-AE99B0D0847E} = {CC594387-4476-425D-9E5A-07FD824D1719} 141 | {381252A5-912B-4B99-B429-8D1029569491} = {61C48C0C-34E9-44B0-B9EA-2033E96FA298} 142 | {942F561E-74D3-44A6-99FA-72D3AC288313} = {61C48C0C-34E9-44B0-B9EA-2033E96FA298} 143 | {26525F44-B7A6-4DA1-8283-A47C4440D8AB} = {61C48C0C-34E9-44B0-B9EA-2033E96FA298} 144 | {0CC64432-4BBC-426D-BED8-52963DD3C67D} = {61C48C0C-34E9-44B0-B9EA-2033E96FA298} 145 | {D434BDDD-1EDA-4212-B6D6-52DD80A08969} = {CC594387-4476-425D-9E5A-07FD824D1719} 146 | {461A55B6-5DB1-44C3-BD71-D286A356C0A8} = {CC594387-4476-425D-9E5A-07FD824D1719} 147 | {DF53F862-9220-4C36-9973-B7E899EA4596} = {CC594387-4476-425D-9E5A-07FD824D1719} 148 | {10BEF5B7-7F3F-4A5C-8B43-B1F2C6637AF9} = {CC594387-4476-425D-9E5A-07FD824D1719} 149 | EndGlobalSection 150 | EndGlobal 151 | -------------------------------------------------------------------------------- /NetLegacySupport.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaladLab/NetLegacySupport/2678ef748bf21245ecb20394f92aaf236e7396e7/NetLegacySupport.snk -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NetLegacySupport 2 | 3 | [![Build status](https://ci.appveyor.com/api/projects/status/0v2wraqkyyltgyg1?svg=true)](https://ci.appveyor.com/project/veblush/netlegacysupport) 4 | [![Coverage Status](https://coveralls.io/repos/github/SaladLab/NetLegacySupport/badge.svg?branch=master)](https://coveralls.io/github/SaladLab/NetLegacySupport?branch=master) 5 | 6 | Library helps supporting old .NET frameworks like .NET 2.0 and 3.5. 7 | This is a backport from .NET Core. Following classes are provided: 8 | 9 | - System.Action 10 | - System.Tuple 11 | - System.Collections.Concurrent.ConcurrentDictionary 12 | 13 | ## System.Action 14 | 15 | Action and Func is quite tricky to use in a multi target framework project because 2.0, 3.0 and 3.5 framework just provided subset of them. 16 | 17 | - .NET Framework 2.0, 3.0 supports only Action\ 18 | - .NET Framework 3.5 supports Action, Func has up to 4 parameters. 19 | - .NET Framework 4.0 supports Action, Func has up to 16 parameters. 20 | 21 | To deal with this problem, this library provides missing classes in target framework. 22 | 23 | #### Where can I get it? 24 | 25 | ``` 26 | PM> Install-Package NetLegacySupport.Action 27 | ``` 28 | 29 | #### Code that you can write. 30 | 31 | ```csharp 32 | Func f = 33 | (a, b, c, d) => { return (long)a + b + c + d; }; 34 | Console.WriteLine(f(1, 2, 3, 4)); // 10 35 | ``` 36 | 37 | ## System.Tuple 38 | 39 | Until .NET Framework 4, tuple was not supported. But it's an essential class that makes your code terse. 40 | 41 | #### Where can I get it? 42 | 43 | ``` 44 | PM> Install-Package NetLegacySupport.Tuple 45 | ``` 46 | 47 | #### Code that you can write. 48 | ```csharp 49 | Tuple t = Tuple.Create(1, "One"); 50 | Console.WriteLine(t); // (1, "One") 51 | ``` 52 | 53 | ## ConcurrentDictionary 54 | 55 | ConcurrentDictionary is quite useful dictionary with a thread-safe feature. 56 | If your project is targeted toward .NET 3.5 only, 57 | [Task Parallel Library for .NET 3.5](https://www.nuget.org/packages/TaskParallelLibrary/) can be an option. 58 | 59 | #### Where can I get it? 60 | 61 | ``` 62 | PM> Install-Package NetLegacySupport.ConcurrentDictionary 63 | ``` 64 | 65 | #### Code that you can write. 66 | 67 | ```csharp 68 | // New instance. (from http://www.dotnetperls.com/concurrentdictionary) 69 | var con = new ConcurrentDictionary(); 70 | con.TryAdd("cat", 1); 71 | con.TryAdd("dog", 2); 72 | 73 | // Try to update if value is 4 (this fails). 74 | con.TryUpdate("cat", 200, 4); 75 | 76 | // Try to update if value is 1 (this works). 77 | con.TryUpdate("cat", 100, 1); 78 | 79 | // Write new value. 80 | Console.WriteLine(con["cat"]); 81 | ``` 82 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 1.1.0.{build} 2 | os: Visual Studio 2015 3 | environment: 4 | NUGETKEY: 5 | secure: z2fJQckgBQJ7IKfjOyrZYPM2+xDj4xYuqaUDBG7MrJs+b1bNc0vzYMTxpF6Sb1mA 6 | COVERALLSKEY: 7 | secure: Zyppdxjp/FCADlmcIWWEz+hDqNLwdUYXoI0gOkqs2M9ZRXOeRDdEHp8ALb3Mr+CD 8 | test: off 9 | build_script: 10 | - cmd: build.cmd ci nugetkey=%NUGETKEY% nugetpublishurl=https://www.myget.org/F/saladlab/api/v2/package nugetprerelease=%APPVEYOR_BUILD_NUMBER% coverallskey=%COVERALLSKEY% 11 | artifacts: 12 | - path: './bin/nuget/*.nupkg' 13 | name: NugetPackage 14 | - path: './bin/unity/*.unitypackage' 15 | name: UnityPackage 16 | cache: 17 | - packages -> **\packages.config 18 | -------------------------------------------------------------------------------- /build.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | pushd %~dp0 4 | 5 | SET PACKAGEPATH=.\packages\ 6 | SET NUGET=.\tools\nuget\NuGet.exe 7 | SET NUGETOPTIONS=-ConfigFile .\tools\nuget\NuGet.Config -OutputDirectory %PACKAGEPATH% -ExcludeVersion 8 | 9 | IF NOT EXIST %PACKAGEPATH%FAKE\Ver_4.28.0 ( 10 | RD /S/Q %PACKAGEPATH%FAKE 11 | %NUGET% install FAKE -Version 4.28.0 %NUGETOPTIONS% 12 | COPY NUL %PACKAGEPATH%FAKE\Ver_4.28.0 13 | ) 14 | 15 | IF NOT EXIST %PACKAGEPATH%FAKE.BuildLib\Ver_0.3.6 ( 16 | RD /S/Q %PACKAGEPATH%FAKE.BuildLib 17 | %NUGET% install FAKE.BuildLib -Version 0.3.6 %NUGETOPTIONS% 18 | COPY NUL %PACKAGEPATH%FAKE.BuildLib\Ver_0.3.6 19 | ) 20 | 21 | set encoding=utf-8 22 | "%PACKAGEPATH%FAKE\tools\FAKE.exe" build.fsx %* 23 | 24 | popd 25 | -------------------------------------------------------------------------------- /build.fsx: -------------------------------------------------------------------------------- 1 | #I @"packages/FAKE/tools" 2 | #I @"packages/FAKE.BuildLib/lib/net451" 3 | #r "FakeLib.dll" 4 | #r "BuildLib.dll" 5 | 6 | open Fake 7 | open BuildLib 8 | 9 | let solution = 10 | initSolution 11 | "./NetLegacySupport.sln" "Release" 12 | [ { emptyProject with Name="NetLegacySupport.Action"; 13 | Folder="./core/Action"; 14 | Dependencies=[] }; 15 | { emptyProject with Name="NetLegacySupport.ConcurrentDictionary"; 16 | Folder="./core/ConcurrentDictionary"; 17 | Dependencies=[("NetLegacySupport.Action", "")] }; 18 | { emptyProject with Name="NetLegacySupport.Tuple"; 19 | Folder="./core/Tuple"; 20 | Dependencies=[] } ] 21 | 22 | Target "Clean" <| fun _ -> cleanBin 23 | 24 | Target "AssemblyInfo" <| fun _ -> generateAssemblyInfo solution 25 | 26 | Target "Restore" <| fun _ -> restoreNugetPackages solution 27 | 28 | Target "Build" <| fun _ -> buildSolution solution 29 | 30 | Target "Test" <| fun _ -> testSolution solution 31 | 32 | Target "Cover" <| fun _ -> coverSolution solution 33 | 34 | Target "PackNuget" <| fun _ -> createNugetPackages solution 35 | 36 | Target "PackUnity" <| fun _ -> packUnityPackage "./core/UnityPackage/NetLegacySupport.unitypackage.json" 37 | 38 | Target "Pack" <| fun _ -> () 39 | 40 | Target "PublishNuget" <| fun _ -> publishNugetPackages solution 41 | 42 | Target "PublishUnity" <| fun _ -> () 43 | 44 | Target "Publish" <| fun _ -> () 45 | 46 | Target "CI" <| fun _ -> () 47 | 48 | Target "Help" <| fun _ -> 49 | showUsage solution (fun _ -> None) 50 | 51 | "Clean" 52 | ==> "AssemblyInfo" 53 | ==> "Restore" 54 | ==> "Build" 55 | ==> "Test" 56 | 57 | "Build" ==> "Cover" 58 | 59 | let isPublishOnly = getBuildParam "publishonly" 60 | 61 | "Build" ==> "PackNuget" =?> ("PublishNuget", isPublishOnly = "") 62 | "Build" ==> "PackUnity" =?> ("PublishUnity", isPublishOnly = "") 63 | "PackNuget" ==> "Pack" 64 | "PackUnity" ==> "Pack" 65 | "PublishNuget" ==> "Publish" 66 | "PublishUnity" ==> "Publish" 67 | 68 | "Test" ==> "CI" 69 | "Cover" ==> "CI" 70 | "Publish" ==> "CI" 71 | 72 | RunTargetOrDefault "Help" 73 | -------------------------------------------------------------------------------- /core/Action.Net20.Tests/Action.Net20.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {ADFB6063-D389-4E26-9A82-A57D6AF1811E} 8 | Library 9 | Properties 10 | System 11 | NetLegacySupport.Action.Tests 12 | v2.0 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE;NET20 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE;NET20 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\..\packages\NUnit.3.0.1\lib\net20\nunit.framework.dll 35 | True 36 | 37 | 38 | 39 | 40 | 41 | TestAction.cs 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | {f1cba647-ca9e-40d6-b54f-e14f7205ac15} 51 | Action.Net20 52 | 53 | 54 | 55 | 56 | 57 | 58 | 65 | -------------------------------------------------------------------------------- /core/Action.Net20.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Action.Net20.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("SaladLab")] 12 | [assembly: AssemblyProduct("Action.Net20.Tests")] 13 | [assembly: AssemblyCopyright("Copyright © 2016 SaladLab")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("adfb6063-d389-4e26-9a82-a57d6af1811e")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /core/Action.Net20.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /core/Action.Net20/Action.Net20.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {F1CBA647-CA9E-40D6-B54F-E14F7205AC15} 8 | Library 9 | Properties 10 | System 11 | NetLegacySupport.Action 12 | v2.0 13 | 512 14 | true 15 | ..\..\NetLegacySupport.snk 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | TRACE;DEBUG;NET20 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE;NET20 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | Properties\AssemblyInfo.cs 40 | 41 | 42 | Properties\AssemblyInfoGenerated.cs 43 | 44 | 45 | System\Action.cs 46 | 47 | 48 | 49 | 56 | -------------------------------------------------------------------------------- /core/Action.Net35.Tests/Action.Net35.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {DCD8CA2C-5675-4F71-9C45-A1C3D463944A} 8 | Library 9 | Properties 10 | System 11 | NetLegacySupport.Action.Tests 12 | v3.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE;NET35 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE;NET35 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\..\packages\NUnit.3.0.1\lib\net20\nunit.framework.dll 35 | True 36 | 37 | 38 | 39 | 40 | 41 | TestAction.cs 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | {2e4cc3ac-0f6e-4ffa-a6e4-722ae7f5d04d} 51 | Action.Net35 52 | 53 | 54 | 55 | 56 | 57 | 58 | 65 | -------------------------------------------------------------------------------- /core/Action.Net35.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Action.Net35.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("SaladLab")] 12 | [assembly: AssemblyProduct("Action.Net35.Tests")] 13 | [assembly: AssemblyCopyright("Copyright © 2016 SaladLab")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("dcd8ca2c-5675-4f71-9c45-a1c3d463944a")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /core/Action.Net35.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /core/Action.Net35/Action.Net35.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {2E4CC3AC-0F6E-4FFA-A6E4-722AE7F5D04D} 8 | Library 9 | Properties 10 | System 11 | NetLegacySupport.Action 12 | v3.5 13 | 512 14 | true 15 | ..\..\NetLegacySupport.snk 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | TRACE;DEBUG;NET35 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE;NET35 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | Properties\AssemblyInfo.cs 40 | 41 | 42 | Properties\AssemblyInfoGenerated.cs 43 | 44 | 45 | System\Action.cs 46 | 47 | 48 | 49 | 56 | -------------------------------------------------------------------------------- /core/Action.Net40.Tests/Action.Net40.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {828C75BE-363B-4DD9-951C-43660B3BCB8B} 8 | Library 9 | Properties 10 | System 11 | NetLegacySupport.Action.Tests 12 | v4.0 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE;NET40 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE;NET40 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\..\packages\NUnit.3.0.1\lib\net40\nunit.framework.dll 35 | True 36 | 37 | 38 | 39 | 40 | 41 | TestAction.cs 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | {8e41d66f-aacc-4d7c-8766-dfd20704a3d2} 54 | Action.Net40 55 | 56 | 57 | 58 | 65 | -------------------------------------------------------------------------------- /core/Action.Net40.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Action.Net40.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("SaladLab")] 12 | [assembly: AssemblyProduct("Action.Net40.Tests")] 13 | [assembly: AssemblyCopyright("Copyright © 2016 SaladLab")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("828c75be-363b-4dd9-951c-43660b3bcb8b")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /core/Action.Net40.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /core/Action.Net40/Action.Net40.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {8E41D66F-AACC-4D7C-8766-DFD20704A3D2} 8 | Library 9 | Properties 10 | System 11 | NetLegacySupport.Action 12 | v4.0 13 | 512 14 | true 15 | ..\..\NetLegacySupport.snk 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | Properties\AssemblyInfo.cs 40 | 41 | 42 | Properties\AssemblyInfoGenerated.cs 43 | 44 | 45 | System\Action.cs 46 | 47 | 48 | 49 | 56 | -------------------------------------------------------------------------------- /core/Action.Tests/TestAction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using NUnit.Framework; 5 | 6 | namespace NetLegacySupport.Action.Tests 7 | { 8 | public class TestAction : AssertionHelper 9 | { 10 | private static void Test() { } 11 | private static void Test(int a1) { } 12 | private static void Test(int a1, int a2) { } 13 | private static void Test(int a1, int a2, int a3) { } 14 | private static void Test(int a1, int a2, int a3, int a4) { } 15 | private static void Test(int a1, int a2, int a3, int a4, int a5) { } 16 | private static void Test(int a1, int a2, int a3, int a4, int a5, int a6) { } 17 | private static void Test(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { } 18 | private static void Test(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { } 19 | 20 | private static int Return() { return 0; } 21 | private static int Return(int a1) { return 0; } 22 | private static int Return(int a1, int a2) { return 0; } 23 | private static int Return(int a1, int a2, int a3) { return 0; } 24 | private static int Return(int a1, int a2, int a3, int a4) { return 0; } 25 | private static int Return(int a1, int a2, int a3, int a4, int a5) { return 0; } 26 | private static int Return(int a1, int a2, int a3, int a4, int a5, int a6) { return 0; } 27 | private static int Return(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { return 0; } 28 | private static int Return(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { return 0; } 29 | 30 | [Test] 31 | public static void TestAction_0() 32 | { 33 | Assert.NotNull(new System.Action(Test)); 34 | } 35 | 36 | [Test] 37 | public static void TestAction_1() 38 | { 39 | Assert.NotNull(new System.Action(Test)); 40 | } 41 | 42 | [Test] 43 | public static void TestAction_2() 44 | { 45 | Assert.NotNull(new System.Action(Test)); 46 | } 47 | 48 | [Test] 49 | public static void TestAction_3() 50 | { 51 | Assert.NotNull(new System.Action(Test)); 52 | } 53 | 54 | [Test] 55 | public static void TestAction_4() 56 | { 57 | Assert.NotNull(new System.Action(Test)); 58 | } 59 | 60 | [Test] 61 | public static void TestAction_5() 62 | { 63 | Assert.NotNull(new System.Action(Test)); 64 | } 65 | 66 | [Test] 67 | public static void TestAction_6() 68 | { 69 | Assert.NotNull(new System.Action(Test)); 70 | } 71 | 72 | [Test] 73 | public static void TestAction_7() 74 | { 75 | Assert.NotNull(new System.Action(Test)); 76 | } 77 | 78 | [Test] 79 | public static void TestAction_8() 80 | { 81 | Assert.NotNull(new System.Action(Test)); 82 | } 83 | 84 | [Test] 85 | public static void TestFunc_0() 86 | { 87 | Assert.NotNull(new System.Func(Return)); 88 | } 89 | 90 | [Test] 91 | public static void TestFunc_1() 92 | { 93 | Assert.NotNull(new System.Func(Return)); 94 | } 95 | 96 | [Test] 97 | public static void TestFunc_2() 98 | { 99 | Assert.NotNull(new System.Func(Return)); 100 | } 101 | 102 | [Test] 103 | public static void TestFunc_3() 104 | { 105 | Assert.NotNull(new System.Func(Return)); 106 | } 107 | 108 | [Test] 109 | public static void TestFunc_4() 110 | { 111 | Assert.NotNull(new System.Func(Return)); 112 | } 113 | 114 | [Test] 115 | public static void TestFunc_5() 116 | { 117 | Assert.NotNull(new System.Func(Return)); 118 | } 119 | 120 | [Test] 121 | public static void TestFunc_6() 122 | { 123 | Assert.NotNull(new System.Func(Return)); 124 | } 125 | 126 | [Test] 127 | public static void TestFunc_7() 128 | { 129 | Assert.NotNull(new System.Func(Return)); 130 | } 131 | 132 | [Test] 133 | public static void TestFunc_8() 134 | { 135 | Assert.NotNull(new System.Func(Return)); 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /core/Action/NetLegacySupport.Action.Release.md: -------------------------------------------------------------------------------- 1 | ## 1.1.1 (Released 2016/09/07) 2 | 3 | * Make an assembly strong-named. 4 | 5 | ## 1.1.0 (Released 2015/12/10) 6 | 7 | * Set AssemblyVersion to 1.0.0 to make a compatible dll. 8 | 9 | ## 1.0.3 (Released 2015/09/21) 10 | 11 | * Initial Release 12 | -------------------------------------------------------------------------------- /core/Action/NetLegacySupport.Action.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | @project@ 5 | @project@@title@ 6 | @build.number@ 7 | Microsoft 8 | Esun Kim 9 | System.Action and System.Func for .NET Framework 2.0, 3.5. This is a backport from .NET Core. 10 | https://github.com/SaladLab/NetLegacySupport 11 | https://raw.githubusercontent.com/SaladLab/NetLegacySupport/master/LICENSE 12 | false 13 | @releaseNotes@ 14 | .net framework legacy support action func 15 | @dependencies@ 16 | @references@ 17 | 18 | 19 | -------------------------------------------------------------------------------- /core/Action/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("NetLegacySupport.Action")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("SaladLab")] 12 | [assembly: AssemblyProduct("NetLegacySupport.Action")] 13 | [assembly: AssemblyCopyright("Copyright © 2016 SaladLab")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("74075621-f658-4a8d-96ff-b05413a7a77a")] 24 | -------------------------------------------------------------------------------- /core/Action/Properties/AssemblyInfoGenerated.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System.Reflection; 3 | 4 | [assembly: AssemblyVersionAttribute("1.0.0")] 5 | [assembly: AssemblyFileVersionAttribute("1.1.1")] 6 | [assembly: AssemblyInformationalVersionAttribute("1.1.1")] 7 | namespace System { 8 | internal static class AssemblyVersionInformation { 9 | internal const string Version = "1.0.0"; 10 | internal const string InformationalVersion = "1.1.1"; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /core/Action/System/Action.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | #if NET20 || NET35 5 | 6 | namespace System 7 | { 8 | // public delegate void Action(T obj); 9 | 10 | #if NET20 11 | public delegate void Action(); 12 | public delegate void Action(T1 arg1, T2 arg2); 13 | public delegate void Action(T1 arg1, T2 arg2, T3 arg3); 14 | public delegate void Action(T1 arg1, T2 arg2, T3 arg3, T4 arg4); 15 | 16 | public delegate TResult Func(); 17 | public delegate TResult Func(T arg); 18 | public delegate TResult Func(T1 arg1, T2 arg2); 19 | public delegate TResult Func(T1 arg1, T2 arg2, T3 arg3); 20 | public delegate TResult Func(T1 arg1, T2 arg2, T3 arg3, T4 arg4); 21 | #endif 22 | 23 | public delegate void Action(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5); 24 | public delegate void Action(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6); 25 | public delegate void Action(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7); 26 | public delegate void Action(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8); 27 | 28 | public delegate TResult Func(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5); 29 | public delegate TResult Func(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6); 30 | public delegate TResult Func(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7); 31 | public delegate TResult Func(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8); 32 | 33 | // More 34 | 35 | public delegate void Action(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9); 36 | public delegate void Action(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10); 37 | public delegate void Action(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11); 38 | public delegate void Action(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12); 39 | public delegate void Action(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13); 40 | public delegate void Action(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14); 41 | public delegate void Action(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15); 42 | public delegate void Action(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16); 43 | 44 | public delegate TResult Func(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9); 45 | public delegate TResult Func(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10); 46 | public delegate TResult Func(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11); 47 | public delegate TResult Func(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12); 48 | public delegate TResult Func(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13); 49 | public delegate TResult Func(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14); 50 | public delegate TResult Func(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15); 51 | public delegate TResult Func(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16); 52 | } 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /core/ConcurrentDictionary.Net20.Tests/ConcurrentDictionary.Net20.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {AEDDF472-2B32-4360-9E91-885B00D692DF} 8 | Library 9 | Properties 10 | System 11 | NetLegacySupport.ConcurrentDictionary.Tests 12 | v2.0 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE;NET20 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE;NET20 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\..\packages\NUnit.3.0.1\lib\net20\nunit.framework.dll 35 | True 36 | 37 | 38 | 39 | 40 | 41 | ConcurrentDictionaryTests.cs 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | {f1cba647-ca9e-40d6-b54f-e14f7205ac15} 51 | Action.Net20 52 | 53 | 54 | {f4e37673-d6cc-4320-8aa6-67234e0034c6} 55 | ConcurrentDictionary.Net20 56 | 57 | 58 | 59 | 60 | 61 | 62 | 69 | -------------------------------------------------------------------------------- /core/ConcurrentDictionary.Net20.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ConcurrentDictionary.Net20.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("SaladLab")] 12 | [assembly: AssemblyProduct("ConcurrentDictionary.Net20.Tests")] 13 | [assembly: AssemblyCopyright("Copyright © 2016 SaladLab")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("aeddf472-2b32-4360-9e91-885b00d692df")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /core/ConcurrentDictionary.Net20.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /core/ConcurrentDictionary.Net20/ConcurrentDictionary.Net20.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {F4E37673-D6CC-4320-8AA6-67234E0034C6} 8 | Library 9 | Properties 10 | System 11 | NetLegacySupport.ConcurrentDictionary 12 | v2.0 13 | 512 14 | true 15 | ..\..\NetLegacySupport.snk 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | TRACE;DEBUG;NET20 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE;NET20 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | Properties\AssemblyInfo.cs 40 | 41 | 42 | Properties\AssemblyInfoGenerated.cs 43 | 44 | 45 | System\Collections\Concurrent\ConcurrentDictionary.cs 46 | 47 | 48 | System\Collections\Concurrent\FrameworkTraits.cs 49 | 50 | 51 | 52 | 53 | 54 | {f1cba647-ca9e-40d6-b54f-e14f7205ac15} 55 | Action.Net20 56 | 57 | 58 | 59 | 66 | -------------------------------------------------------------------------------- /core/ConcurrentDictionary.Net35.Tests/ConcurrentDictionary.Net35.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {942F561E-74D3-44A6-99FA-72D3AC288313} 8 | Library 9 | Properties 10 | System 11 | NetLegacySupport.ConcurrentDictionary.Tests 12 | v3.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE;NET35 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE;NET35 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\..\packages\NUnit.3.0.1\lib\net20\nunit.framework.dll 35 | True 36 | 37 | 38 | 39 | 40 | 41 | ConcurrentDictionaryTests.cs 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | {2e4cc3ac-0f6e-4ffa-a6e4-722ae7f5d04d} 51 | Action.Net35 52 | 53 | 54 | {381252a5-912b-4b99-b429-8d1029569491} 55 | ConcurrentDictionary.Net35 56 | 57 | 58 | 59 | 60 | 61 | 62 | 69 | -------------------------------------------------------------------------------- /core/ConcurrentDictionary.Net35.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ConcurrentDictionary.Net35.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("SaladLab")] 12 | [assembly: AssemblyProduct("ConcurrentDictionary.Net35.Tests")] 13 | [assembly: AssemblyCopyright("Copyright © 2016 SaladLab")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("942f561e-74d3-44a6-99fa-72d3ac288313")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /core/ConcurrentDictionary.Net35.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /core/ConcurrentDictionary.Net35/ConcurrentDictionary.Net35.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {381252A5-912B-4B99-B429-8D1029569491} 8 | Library 9 | Properties 10 | System 11 | NetLegacySupport.ConcurrentDictionary 12 | v3.5 13 | 512 14 | true 15 | ..\..\NetLegacySupport.snk 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE;NET35 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE;NET35 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | Properties\AssemblyInfo.cs 40 | 41 | 42 | Properties\AssemblyInfoGenerated.cs 43 | 44 | 45 | System\Collections\Concurrent\ConcurrentDictionary.cs 46 | 47 | 48 | System\Collections\Concurrent\FrameworkTraits.cs 49 | 50 | 51 | 52 | 59 | -------------------------------------------------------------------------------- /core/ConcurrentDictionary.Net40.Tests/ConcurrentDictionary.Net40.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {0CC64432-4BBC-426D-BED8-52963DD3C67D} 8 | Library 9 | Properties 10 | System 11 | NetLegacySupport.ConcurrentDictionary.Tests 12 | v4.0 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE;NET40 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE;NET40 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\..\packages\NUnit.3.0.1\lib\net40\nunit.framework.dll 35 | True 36 | 37 | 38 | 39 | 40 | 41 | ConcurrentDictionaryTests.cs 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | {8e41d66f-aacc-4d7c-8766-dfd20704a3d2} 51 | Action.Net40 52 | 53 | 54 | {26525f44-b7a6-4da1-8283-a47c4440d8ab} 55 | ConcurrentDictionary.Net40 56 | 57 | 58 | 59 | 60 | 61 | 62 | 69 | -------------------------------------------------------------------------------- /core/ConcurrentDictionary.Net40.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ConcurrentDictionary.Net40.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("SaladLab")] 12 | [assembly: AssemblyProduct("ConcurrentDictionary.Net40.Tests")] 13 | [assembly: AssemblyCopyright("Copyright © 2016 SaladLab")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("0cc64432-4bbc-426d-bed8-52963dd3c67d")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /core/ConcurrentDictionary.Net40.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /core/ConcurrentDictionary.Net40/ConcurrentDictionary.Net40.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {26525F44-B7A6-4DA1-8283-A47C4440D8AB} 8 | Library 9 | Properties 10 | System 11 | NetLegacySupport.ConcurrentDictionary 12 | v4.0 13 | 512 14 | true 15 | ..\..\NetLegacySupport.snk 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE;NET40 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE;NET40 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | Properties\AssemblyInfo.cs 40 | 41 | 42 | Properties\AssemblyInfoGenerated.cs 43 | 44 | 45 | System\Collections\Concurrent\ConcurrentDictionary.cs 46 | 47 | 48 | System\Collections\Concurrent\FrameworkTraits.cs 49 | 50 | 51 | 52 | 59 | -------------------------------------------------------------------------------- /core/ConcurrentDictionary.Tests/ConcurrentDictionaryTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Collections.Generic; 5 | using System.Diagnostics; 6 | using System.Threading; 7 | // using System.Threading.Tasks; 8 | using NUnit.Framework; 9 | 10 | namespace System.Collections.Concurrent.Tests 11 | { 12 | public class ConcurrentDictionaryTests : AssertionHelper 13 | { 14 | /* 15 | [Test] 16 | public static void TestBasicScenarios() 17 | { 18 | ConcurrentDictionary cd = new ConcurrentDictionary(); 19 | 20 | Task[] tks = new Task[2]; 21 | tks[0] = Task.Run(() => 22 | { 23 | var ret = cd.TryAdd(1, 11); 24 | if (!ret) 25 | { 26 | ret = cd.TryUpdate(1, 11, 111); 27 | Assert.True(ret); 28 | } 29 | 30 | ret = cd.TryAdd(2, 22); 31 | if (!ret) 32 | { 33 | ret = cd.TryUpdate(2, 22, 222); 34 | Assert.True(ret); 35 | } 36 | }); 37 | 38 | tks[1] = Task.Run(() => 39 | { 40 | var ret = cd.TryAdd(2, 222); 41 | if (!ret) 42 | { 43 | ret = cd.TryUpdate(2, 222, 22); 44 | Assert.True(ret); 45 | } 46 | 47 | ret = cd.TryAdd(1, 111); 48 | if (!ret) 49 | { 50 | ret = cd.TryUpdate(1, 111, 11); 51 | Assert.True(ret); 52 | } 53 | }); 54 | 55 | Task.WaitAll(tks); 56 | } 57 | */ 58 | 59 | /* 60 | [Test] 61 | public static void TestAdd1() 62 | { 63 | TestAdd1(1, 1, 1, 10000); 64 | TestAdd1(5, 1, 1, 10000); 65 | TestAdd1(1, 1, 2, 5000); 66 | TestAdd1(1, 1, 5, 2000); 67 | TestAdd1(4, 0, 4, 2000); 68 | TestAdd1(16, 31, 4, 2000); 69 | TestAdd1(64, 5, 5, 5000); 70 | TestAdd1(5, 5, 5, 2500); 71 | } 72 | 73 | private static void TestAdd1(int cLevel, int initSize, int threads, int addsPerThread) 74 | { 75 | ConcurrentDictionary dictConcurrent = new ConcurrentDictionary(cLevel, 1); 76 | IDictionary dict = dictConcurrent; 77 | 78 | int count = threads; 79 | using (ManualResetEvent mre = new ManualResetEvent(false)) 80 | { 81 | for (int i = 0; i < threads; i++) 82 | { 83 | int ii = i; 84 | Task.Run( 85 | () => 86 | { 87 | for (int j = 0; j < addsPerThread; j++) 88 | { 89 | dict.Add(j + ii * addsPerThread, -(j + ii * addsPerThread)); 90 | } 91 | if (Interlocked.Decrement(ref count) == 0) mre.Set(); 92 | }); 93 | } 94 | mre.WaitOne(); 95 | } 96 | 97 | foreach (var pair in dict) 98 | { 99 | Assert.AreEqual(pair.Key, -pair.Value); 100 | } 101 | 102 | List gotKeys = new List(); 103 | foreach (var pair in dict) 104 | gotKeys.Add(pair.Key); 105 | 106 | gotKeys.Sort(); 107 | 108 | List expectKeys = new List(); 109 | int itemCount = threads * addsPerThread; 110 | for (int i = 0; i < itemCount; i++) 111 | expectKeys.Add(i); 112 | 113 | Assert.AreEqual(expectKeys.Count, gotKeys.Count); 114 | 115 | for (int i = 0; i < expectKeys.Count; i++) 116 | { 117 | Assert.True(expectKeys[i].Equals(gotKeys[i]), 118 | String.Format("The set of keys in the dictionary is are not the same as the expected" + Environment.NewLine + 119 | "TestAdd1(cLevel={0}, initSize={1}, threads={2}, addsPerThread={3})", cLevel, initSize, threads, addsPerThread) 120 | ); 121 | } 122 | 123 | // Finally, let's verify that the count is reported correctly. 124 | int expectedCount = threads * addsPerThread; 125 | Assert.AreEqual(expectedCount, dict.Count); 126 | Assert.AreEqual(expectedCount, dictConcurrent.ToArray().Length); 127 | } 128 | */ 129 | 130 | /* 131 | [Test] 132 | public static void TestUpdate1() 133 | { 134 | TestUpdate1(1, 1, 10000); 135 | TestUpdate1(5, 1, 10000); 136 | TestUpdate1(1, 2, 5000); 137 | TestUpdate1(1, 5, 2001); 138 | TestUpdate1(4, 4, 2001); 139 | TestUpdate1(15, 5, 2001); 140 | TestUpdate1(64, 5, 5000); 141 | TestUpdate1(5, 5, 25000); 142 | } 143 | 144 | private static void TestUpdate1(int cLevel, int threads, int updatesPerThread) 145 | { 146 | IDictionary dict = new ConcurrentDictionary(cLevel, 1); 147 | 148 | for (int i = 1; i <= updatesPerThread; i++) dict[i] = i; 149 | 150 | int running = threads; 151 | using (ManualResetEvent mre = new ManualResetEvent(false)) 152 | { 153 | for (int i = 0; i < threads; i++) 154 | { 155 | int ii = i; 156 | Task.Run( 157 | () => 158 | { 159 | for (int j = 1; j <= updatesPerThread; j++) 160 | { 161 | dict[j] = (ii + 2) * j; 162 | } 163 | if (Interlocked.Decrement(ref running) == 0) mre.Set(); 164 | }); 165 | } 166 | mre.WaitOne(); 167 | } 168 | 169 | foreach (var pair in dict) 170 | { 171 | var div = pair.Value / pair.Key; 172 | var rem = pair.Value % pair.Key; 173 | 174 | Assert.AreEqual(0, rem); 175 | Assert.True(div > 1 && div <= threads+1, 176 | String.Format("* Invalid value={3}! TestUpdate1(cLevel={0}, threads={1}, updatesPerThread={2})", cLevel, threads, updatesPerThread, div)); 177 | } 178 | 179 | List gotKeys = new List(); 180 | foreach (var pair in dict) 181 | gotKeys.Add(pair.Key); 182 | gotKeys.Sort(); 183 | 184 | List expectKeys = new List(); 185 | for (int i = 1; i <= updatesPerThread; i++) 186 | expectKeys.Add(i); 187 | 188 | Assert.AreEqual(expectKeys.Count, gotKeys.Count); 189 | 190 | for (int i = 0; i < expectKeys.Count; i++) 191 | { 192 | Assert.True(expectKeys[i].Equals(gotKeys[i]), 193 | String.Format("The set of keys in the dictionary is are not the same as the expected." + Environment.NewLine + 194 | "TestUpdate1(cLevel={0}, threads={1}, updatesPerThread={2})", cLevel, threads, updatesPerThread) 195 | ); 196 | } 197 | } 198 | */ 199 | 200 | /* 201 | [Test] 202 | public static void TestRead1() 203 | { 204 | TestRead1(1, 1, 10000); 205 | TestRead1(5, 1, 10000); 206 | TestRead1(1, 2, 5000); 207 | TestRead1(1, 5, 2001); 208 | TestRead1(4, 4, 2001); 209 | TestRead1(15, 5, 2001); 210 | TestRead1(64, 5, 5000); 211 | TestRead1(5, 5, 25000); 212 | } 213 | 214 | private static void TestRead1(int cLevel, int threads, int readsPerThread) 215 | { 216 | IDictionary dict = new ConcurrentDictionary(cLevel, 1); 217 | 218 | for (int i = 0; i < readsPerThread; i += 2) dict[i] = i; 219 | 220 | int count = threads; 221 | using (ManualResetEvent mre = new ManualResetEvent(false)) 222 | { 223 | for (int i = 0; i < threads; i++) 224 | { 225 | int ii = i; 226 | Task.Run( 227 | () => 228 | { 229 | for (int j = 0; j < readsPerThread; j++) 230 | { 231 | int val = 0; 232 | if (dict.TryGetValue(j, out val)) 233 | { 234 | if (j % 2 == 1 || j != val) 235 | { 236 | Console.WriteLine("* TestRead1(cLevel={0}, threads={1}, readsPerThread={2})", cLevel, threads, readsPerThread); 237 | Assert.False(true, " > FAILED. Invalid element in the dictionary."); 238 | } 239 | } 240 | else 241 | { 242 | if (j % 2 == 0) 243 | { 244 | Console.WriteLine("* TestRead1(cLevel={0}, threads={1}, readsPerThread={2})", cLevel, threads, readsPerThread); 245 | Assert.False(true, " > FAILED. Element missing from the dictionary"); 246 | } 247 | } 248 | } 249 | if (Interlocked.Decrement(ref count) == 0) mre.Set(); 250 | }); 251 | } 252 | mre.WaitOne(); 253 | } 254 | } 255 | */ 256 | 257 | /* 258 | [Test] 259 | public static void TestRemove1() 260 | { 261 | TestRemove1(1, 1, 10000); 262 | TestRemove1(5, 1, 1000); 263 | TestRemove1(1, 5, 2001); 264 | TestRemove1(4, 4, 2001); 265 | TestRemove1(15, 5, 2001); 266 | TestRemove1(64, 5, 5000); 267 | } 268 | 269 | private static void TestRemove1(int cLevel, int threads, int removesPerThread) 270 | { 271 | ConcurrentDictionary dict = new ConcurrentDictionary(cLevel, 1); 272 | string methodparameters = string.Format("* TestRemove1(cLevel={0}, threads={1}, removesPerThread={2})", cLevel, threads, removesPerThread); 273 | int N = 2 * threads * removesPerThread; 274 | 275 | for (int i = 0; i < N; i++) dict[i] = -i; 276 | 277 | // The dictionary contains keys [0..N), each key mapped to a value equal to the key. 278 | // Threads will cooperatively remove all even keys 279 | 280 | int running = threads; 281 | using (ManualResetEvent mre = new ManualResetEvent(false)) 282 | { 283 | for (int i = 0; i < threads; i++) 284 | { 285 | int ii = i; 286 | Task.Run( 287 | () => 288 | { 289 | for (int j = 0; j < removesPerThread; j++) 290 | { 291 | int value; 292 | int key = 2 * (ii + j * threads); 293 | Assert.True(dict.TryRemove(key, out value), "Failed to remove an element! " + methodparameters); 294 | 295 | Assert.AreEqual(-key, value); 296 | } 297 | 298 | if (Interlocked.Decrement(ref running) == 0) mre.Set(); 299 | }); 300 | } 301 | mre.WaitOne(); 302 | } 303 | 304 | foreach (var pair in dict) 305 | { 306 | Assert.AreEqual(pair.Key, -pair.Value); 307 | } 308 | 309 | List gotKeys = new List(); 310 | foreach (var pair in dict) 311 | gotKeys.Add(pair.Key); 312 | gotKeys.Sort(); 313 | 314 | List expectKeys = new List(); 315 | for (int i = 0; i < (threads * removesPerThread); i++) 316 | expectKeys.Add(2 * i + 1); 317 | 318 | Assert.AreEqual(expectKeys.Count, gotKeys.Count); 319 | 320 | for (int i = 0; i < expectKeys.Count; i++) 321 | { 322 | Assert.True(expectKeys[i].Equals(gotKeys[i]), " > Unexpected key value! " + methodparameters); 323 | } 324 | 325 | // Finally, let's verify that the count is reported correctly. 326 | Assert.AreEqual(expectKeys.Count, dict.Count); 327 | Assert.AreEqual(expectKeys.Count, dict.ToArray().Length); 328 | } 329 | */ 330 | 331 | /* 332 | [Test] 333 | public static void TestRemove2() 334 | { 335 | TestRemove2(1); 336 | TestRemove2(10); 337 | TestRemove2(5000); 338 | } 339 | 340 | private static void TestRemove2(int removesPerThread) 341 | { 342 | ConcurrentDictionary dict = new ConcurrentDictionary(); 343 | 344 | for (int i = 0; i < removesPerThread; i++) dict[i] = -i; 345 | 346 | // The dictionary contains keys [0..N), each key mapped to a value equal to the key. 347 | // Threads will cooperatively remove all even keys. 348 | const int SIZE = 2; 349 | int running = SIZE; 350 | 351 | bool[][] seen = new bool[SIZE][]; 352 | for (int i = 0; i < SIZE; i++) seen[i] = new bool[removesPerThread]; 353 | 354 | using (ManualResetEvent mre = new ManualResetEvent(false)) 355 | { 356 | for (int t = 0; t < SIZE; t++) 357 | { 358 | int thread = t; 359 | Task.Run( 360 | () => 361 | { 362 | for (int key = 0; key < removesPerThread; key++) 363 | { 364 | int value; 365 | if (dict.TryRemove(key, out value)) 366 | { 367 | seen[thread][key] = true; 368 | 369 | Assert.AreEqual(-key, value); 370 | } 371 | } 372 | if (Interlocked.Decrement(ref running) == 0) mre.Set(); 373 | }); 374 | } 375 | mre.WaitOne(); 376 | } 377 | 378 | Assert.AreEqual(0, dict.Count); 379 | 380 | for (int i = 0; i < removesPerThread; i++) 381 | { 382 | Assert.False(seen[0][i] == seen[1][i], 383 | String.Format("> FAILED. Two threads appear to have removed the same element. TestRemove2(removesPerThread={0})", removesPerThread) 384 | ); 385 | } 386 | } 387 | */ 388 | 389 | [Test] 390 | public static void TestRemove3() 391 | { 392 | ConcurrentDictionary dict = new ConcurrentDictionary(); 393 | 394 | dict[99] = -99; 395 | 396 | ICollection> col = dict; 397 | 398 | // Make sure we cannot "remove" a key/value pair which is not in the dictionary 399 | for (int i = 0; i < 200; i++) 400 | { 401 | if (i != 99) 402 | { 403 | Assert.False(col.Remove(new KeyValuePair(i, -99)), "Should not remove not existing a key/value pair - new KeyValuePair(i, -99)"); 404 | Assert.False(col.Remove(new KeyValuePair(99, -i)), "Should not remove not existing a key/value pair - new KeyValuePair(99, -i)"); 405 | } 406 | } 407 | 408 | // Can we remove a key/value pair successfully? 409 | Assert.True(col.Remove(new KeyValuePair(99, -99)), "Failed to remove existing key/value pair"); 410 | 411 | // Make sure the key/value pair is gone 412 | Assert.False(col.Remove(new KeyValuePair(99, -99)), "Should not remove the key/value pair which has been removed"); 413 | 414 | // And that the dictionary is empty. We will check the count in a few different ways: 415 | Assert.AreEqual(0, dict.Count); 416 | Assert.AreEqual(0, dict.ToArray().Length); 417 | } 418 | 419 | /* 420 | [Test] 421 | public static void TestGetOrAdd() 422 | { 423 | TestGetOrAddOrUpdate(1, 1, 1, 10000, true); 424 | TestGetOrAddOrUpdate(5, 1, 1, 10000, true); 425 | TestGetOrAddOrUpdate(1, 1, 2, 5000, true); 426 | TestGetOrAddOrUpdate(1, 1, 5, 2000, true); 427 | TestGetOrAddOrUpdate(4, 0, 4, 2000, true); 428 | TestGetOrAddOrUpdate(16, 31, 4, 2000, true); 429 | TestGetOrAddOrUpdate(64, 5, 5, 5000, true); 430 | TestGetOrAddOrUpdate(5, 5, 5, 25000, true); 431 | } 432 | 433 | [Test] 434 | public static void TestAddOrUpdate() 435 | { 436 | TestGetOrAddOrUpdate(1, 1, 1, 10000, false); 437 | TestGetOrAddOrUpdate(5, 1, 1, 10000, false); 438 | TestGetOrAddOrUpdate(1, 1, 2, 5000, false); 439 | TestGetOrAddOrUpdate(1, 1, 5, 2000, false); 440 | TestGetOrAddOrUpdate(4, 0, 4, 2000, false); 441 | TestGetOrAddOrUpdate(16, 31, 4, 2000, false); 442 | TestGetOrAddOrUpdate(64, 5, 5, 5000, false); 443 | TestGetOrAddOrUpdate(5, 5, 5, 25000, false); 444 | } 445 | 446 | private static void TestGetOrAddOrUpdate(int cLevel, int initSize, int threads, int addsPerThread, bool isAdd) 447 | { 448 | ConcurrentDictionary dict = new ConcurrentDictionary(cLevel, 1); 449 | 450 | int count = threads; 451 | using (ManualResetEvent mre = new ManualResetEvent(false)) 452 | { 453 | for (int i = 0; i < threads; i++) 454 | { 455 | int ii = i; 456 | Task.Run( 457 | () => 458 | { 459 | for (int j = 0; j < addsPerThread; j++) 460 | { 461 | if (isAdd) 462 | { 463 | //call either of the two overloads of GetOrAdd 464 | if (j + ii % 2 == 0) 465 | { 466 | dict.GetOrAdd(j, -j); 467 | } 468 | else 469 | { 470 | dict.GetOrAdd(j, x => -x); 471 | } 472 | } 473 | else 474 | { 475 | if (j + ii % 2 == 0) 476 | { 477 | dict.AddOrUpdate(j, -j, (k, v) => -j); 478 | } 479 | else 480 | { 481 | dict.AddOrUpdate(j, (k) => -k, (k, v) => -k); 482 | } 483 | } 484 | } 485 | if (Interlocked.Decrement(ref count) == 0) mre.Set(); 486 | }); 487 | } 488 | mre.WaitOne(); 489 | } 490 | 491 | foreach (var pair in dict) 492 | { 493 | Assert.AreEqual(pair.Key, -pair.Value); 494 | } 495 | 496 | List gotKeys = new List(); 497 | foreach (var pair in dict) 498 | gotKeys.Add(pair.Key); 499 | gotKeys.Sort(); 500 | 501 | List expectKeys = new List(); 502 | for (int i = 0; i < addsPerThread; i++) 503 | expectKeys.Add(i); 504 | 505 | Assert.AreEqual(expectKeys.Count, gotKeys.Count); 506 | 507 | for (int i = 0; i < expectKeys.Count; i++) 508 | { 509 | Assert.True(expectKeys[i].Equals(gotKeys[i]), 510 | String.Format("* Test '{4}': Level={0}, initSize={1}, threads={2}, addsPerThread={3})" + Environment.NewLine + 511 | "> FAILED. The set of keys in the dictionary is are not the same as the expected.", 512 | cLevel, initSize, threads, addsPerThread, isAdd ? "GetOrAdd" : "GetOrUpdate")); 513 | } 514 | 515 | // Finally, let's verify that the count is reported correctly. 516 | Assert.AreEqual(addsPerThread, dict.Count); 517 | Assert.AreEqual(addsPerThread, dict.ToArray().Length); 518 | } 519 | */ 520 | 521 | [Test] 522 | public static void TestBugFix669376() 523 | { 524 | var cd = new ConcurrentDictionary(new OrdinalStringComparer()); 525 | cd["test"] = 10; 526 | Assert.True(cd.ContainsKey("TEST"), "Customized comparer didn't work"); 527 | } 528 | 529 | private class OrdinalStringComparer : IEqualityComparer 530 | { 531 | public bool Equals(string x, string y) 532 | { 533 | var xlower = x.ToLowerInvariant(); 534 | var ylower = y.ToLowerInvariant(); 535 | return string.CompareOrdinal(xlower, ylower) == 0; 536 | } 537 | 538 | public int GetHashCode(string obj) 539 | { 540 | return 0; 541 | } 542 | } 543 | 544 | [Test] 545 | public static void TestConstructor() 546 | { 547 | var dictionary = new ConcurrentDictionary(new[] { new KeyValuePair(1, 1) }); 548 | Assert.False(dictionary.IsEmpty); 549 | Assert.AreEqual(1, dictionary.Keys.Count); 550 | Assert.AreEqual(1, dictionary.Values.Count); 551 | } 552 | 553 | /* 554 | [Test] 555 | public static void TestDebuggerAttributes() 556 | { 557 | DebuggerAttributes.ValidateDebuggerDisplayReferences(new ConcurrentDictionary()); 558 | DebuggerAttributes.ValidateDebuggerTypeProxyProperties(new ConcurrentDictionary()); 559 | } 560 | */ 561 | 562 | [Test] 563 | public static void TestConstructor_Negative() 564 | { 565 | Assert.Throws( 566 | () => new ConcurrentDictionary((ICollection>)null)); 567 | // "TestConstructor: FAILED. Constructor didn't throw ANE when null collection is passed"); 568 | 569 | Assert.Throws( 570 | () => new ConcurrentDictionary((IEqualityComparer)null)); 571 | // "TestConstructor: FAILED. Constructor didn't throw ANE when null IEqualityComparer is passed"); 572 | 573 | Assert.Throws( 574 | () => new ConcurrentDictionary((ICollection>)null, EqualityComparer.Default)); 575 | // "TestConstructor: FAILED. Constructor didn't throw ANE when null collection and non null IEqualityComparer passed"); 576 | 577 | Assert.Throws( 578 | () => new ConcurrentDictionary(new[] { new KeyValuePair(1, 1) }, null)); 579 | // "TestConstructor: FAILED. Constructor didn't throw ANE when non null collection and null IEqualityComparer passed"); 580 | 581 | Assert.Throws( 582 | () => new ConcurrentDictionary(new[] { new KeyValuePair(null, 1) })); 583 | // "TestConstructor: FAILED. Constructor didn't throw ANE when collection has null key passed"); 584 | Assert.Throws( 585 | () => new ConcurrentDictionary(new[] { new KeyValuePair(1, 1), new KeyValuePair(1, 2) })); 586 | // "TestConstructor: FAILED. Constructor didn't throw AE when collection has duplicate keys passed"); 587 | 588 | Assert.Throws( 589 | () => new ConcurrentDictionary(1, null, EqualityComparer.Default)); 590 | // "TestConstructor: FAILED. Constructor didn't throw ANE when null collection is passed"); 591 | 592 | Assert.Throws( 593 | () => new ConcurrentDictionary(1, new[] { new KeyValuePair(1, 1) }, null)); 594 | // "TestConstructor: FAILED. Constructor didn't throw ANE when null comparer is passed"); 595 | 596 | Assert.Throws( 597 | () => new ConcurrentDictionary(1, 1, null)); 598 | // "TestConstructor: FAILED. Constructor didn't throw ANE when null comparer is passed"); 599 | 600 | Assert.Throws( 601 | () => new ConcurrentDictionary(0, 10)); 602 | // "TestConstructor: FAILED. Constructor didn't throw AORE when <1 concurrencyLevel passed"); 603 | 604 | Assert.Throws( 605 | () => new ConcurrentDictionary(-1, 0)); 606 | // "TestConstructor: FAILED. Constructor didn't throw AORE when < 0 capacity passed"); 607 | } 608 | 609 | [Test] 610 | public static void TestExceptions() 611 | { 612 | var dictionary = new ConcurrentDictionary(); 613 | Assert.Throws( 614 | () => dictionary.TryAdd(null, 0)); 615 | // "TestExceptions: FAILED. TryAdd didn't throw ANE when null key is passed"); 616 | 617 | Assert.Throws( 618 | () => dictionary.ContainsKey(null)); 619 | // "TestExceptions: FAILED. Contains didn't throw ANE when null key is passed"); 620 | 621 | int item; 622 | Assert.Throws( 623 | () => dictionary.TryRemove(null, out item)); 624 | // "TestExceptions: FAILED. TryRemove didn't throw ANE when null key is passed"); 625 | Assert.Throws( 626 | () => dictionary.TryGetValue(null, out item)); 627 | // "TestExceptions: FAILED. TryGetValue didn't throw ANE when null key is passed"); 628 | 629 | Assert.Throws( 630 | () => { var x = dictionary[null]; }); 631 | // "TestExceptions: FAILED. this[] didn't throw ANE when null key is passed"); 632 | Assert.Throws( 633 | () => { var x = dictionary["1"]; }); 634 | // "TestExceptions: FAILED. this[] TryGetValue didn't throw KeyNotFoundException!"); 635 | 636 | Assert.Throws( 637 | () => dictionary[null] = 1); 638 | // "TestExceptions: FAILED. this[] didn't throw ANE when null key is passed"); 639 | 640 | Assert.Throws( 641 | () => dictionary.GetOrAdd(null, (k) => 0)); 642 | // "TestExceptions: FAILED. GetOrAdd didn't throw ANE when null key is passed"); 643 | Assert.Throws( 644 | () => dictionary.GetOrAdd("1", null)); 645 | // "TestExceptions: FAILED. GetOrAdd didn't throw ANE when null valueFactory is passed"); 646 | Assert.Throws( 647 | () => dictionary.GetOrAdd(null, 0)); 648 | // "TestExceptions: FAILED. GetOrAdd didn't throw ANE when null key is passed"); 649 | 650 | Assert.Throws( 651 | () => dictionary.AddOrUpdate(null, (k) => 0, (k, v) => 0)); 652 | // "TestExceptions: FAILED. AddOrUpdate didn't throw ANE when null key is passed"); 653 | Assert.Throws( 654 | () => dictionary.AddOrUpdate("1", null, (k, v) => 0)); 655 | // "TestExceptions: FAILED. AddOrUpdate didn't throw ANE when null updateFactory is passed"); 656 | Assert.Throws( 657 | () => dictionary.AddOrUpdate(null, (k) => 0, null)); 658 | // "TestExceptions: FAILED. AddOrUpdate didn't throw ANE when null addFactory is passed"); 659 | 660 | dictionary.TryAdd("1", 1); 661 | Assert.Throws( 662 | () => ((IDictionary)dictionary).Add("1", 2)); 663 | // "TestExceptions: FAILED. IDictionary didn't throw AE when duplicate key is passed"); 664 | } 665 | 666 | [Test] 667 | public static void TestIDictionary() 668 | { 669 | IDictionary dictionary = new ConcurrentDictionary(); 670 | Assert.False(dictionary.IsReadOnly); 671 | 672 | foreach (var entry in dictionary) 673 | { 674 | Assert.False(true, "TestIDictionary: FAILED. GetEnumerator retuned items when the dictionary is empty"); 675 | } 676 | 677 | const int SIZE = 10; 678 | for (int i = 0; i < SIZE; i++) 679 | dictionary.Add(i.ToString(), i); 680 | 681 | Assert.AreEqual(SIZE, dictionary.Count); 682 | 683 | //test contains 684 | Assert.False(dictionary.Contains(1), "TestIDictionary: FAILED. Contain retuned true for incorrect key type"); 685 | Assert.False(dictionary.Contains("100"), "TestIDictionary: FAILED. Contain retuned true for incorrect key"); 686 | Assert.True(dictionary.Contains("1"), "TestIDictionary: FAILED. Contain retuned false for correct key"); 687 | 688 | //test GetEnumerator 689 | int count = 0; 690 | foreach (var obj in dictionary) 691 | { 692 | DictionaryEntry entry = (DictionaryEntry)obj; 693 | string key = (string)entry.Key; 694 | int value = (int)entry.Value; 695 | int expectedValue = int.Parse(key); 696 | Assert.True(value == expectedValue, 697 | String.Format("TestIDictionary: FAILED. Unexpected value returned from GetEnumerator, expected {0}, actual {1}", value, expectedValue)); 698 | count++; 699 | } 700 | 701 | Assert.AreEqual(SIZE, count); 702 | Assert.AreEqual(SIZE, dictionary.Keys.Count); 703 | Assert.AreEqual(SIZE, dictionary.Values.Count); 704 | 705 | //Test Remove 706 | dictionary.Remove("9"); 707 | Assert.AreEqual(SIZE - 1, dictionary.Count); 708 | 709 | //Test this[] 710 | for (int i = 0; i < dictionary.Count; i++) 711 | Assert.AreEqual(i, (int)dictionary[i.ToString()]); 712 | 713 | dictionary["1"] = 100; // try a valid setter 714 | Assert.AreEqual(100, (int)dictionary["1"]); 715 | 716 | //nonsexist key 717 | Assert.Null(dictionary["NotAKey"]); 718 | } 719 | 720 | [Test] 721 | public static void TestIDictionary_Negative() 722 | { 723 | IDictionary dictionary = new ConcurrentDictionary(); 724 | Assert.Throws( 725 | () => dictionary.Add(null, 1)); 726 | // "TestIDictionary: FAILED. Add didn't throw ANE when null key is passed"); 727 | 728 | Assert.Throws( 729 | () => dictionary.Add(1, 1)); 730 | // "TestIDictionary: FAILED. Add didn't throw AE when incorrect key type is passed"); 731 | 732 | Assert.Throws( 733 | () => dictionary.Add("1", "1")); 734 | // "TestIDictionary: FAILED. Add didn't throw AE when incorrect value type is passed"); 735 | 736 | Assert.Throws( 737 | () => dictionary.Contains(null)); 738 | // "TestIDictionary: FAILED. Contain didn't throw ANE when null key is passed"); 739 | 740 | //Test Remove 741 | Assert.Throws( 742 | () => dictionary.Remove(null)); 743 | // "TestIDictionary: FAILED. Remove didn't throw ANE when null key is passed"); 744 | 745 | //Test this[] 746 | Assert.Throws( 747 | () => { object val = dictionary[null]; }); 748 | // "TestIDictionary: FAILED. this[] getter didn't throw ANE when null key is passed"); 749 | Assert.Throws( 750 | () => dictionary[null] = 0); 751 | // "TestIDictionary: FAILED. this[] setter didn't throw ANE when null key is passed"); 752 | 753 | Assert.Throws( 754 | () => dictionary[1] = 0); 755 | // "TestIDictionary: FAILED. this[] setter didn't throw AE when invalid key type is passed"); 756 | 757 | Assert.Throws( 758 | () => dictionary["1"] = "0"); 759 | // "TestIDictionary: FAILED. this[] setter didn't throw AE when invalid value type is passed"); 760 | } 761 | 762 | [Test] 763 | public static void TestICollection() 764 | { 765 | ICollection dictionary = new ConcurrentDictionary(); 766 | Assert.False(dictionary.IsSynchronized, "TestICollection: FAILED. IsSynchronized returned true!"); 767 | 768 | int key = -1; 769 | int value = +1; 770 | //add one item to the dictionary 771 | ((ConcurrentDictionary)dictionary).TryAdd(key, value); 772 | 773 | var objectArray = new Object[1]; 774 | dictionary.CopyTo(objectArray, 0); 775 | 776 | Assert.AreEqual(key, ((KeyValuePair)objectArray[0]).Key); 777 | Assert.AreEqual(value, ((KeyValuePair)objectArray[0]).Value); 778 | 779 | var keyValueArray = new KeyValuePair[1]; 780 | dictionary.CopyTo(keyValueArray, 0); 781 | Assert.AreEqual(key, keyValueArray[0].Key); 782 | Assert.AreEqual(value, keyValueArray[0].Value); 783 | 784 | var entryArray = new DictionaryEntry[1]; 785 | dictionary.CopyTo(entryArray, 0); 786 | Assert.AreEqual(key, (int)entryArray[0].Key); 787 | Assert.AreEqual(value, (int)entryArray[0].Value); 788 | } 789 | 790 | [Test] 791 | public static void TestICollection_Negative() 792 | { 793 | ICollection dictionary = new ConcurrentDictionary(); 794 | Assert.False(dictionary.IsSynchronized, "TestICollection: FAILED. IsSynchronized returned true!"); 795 | 796 | Assert.Throws(() => { var obj = dictionary.SyncRoot; }); 797 | // "TestICollection: FAILED. SyncRoot property didn't throw"); 798 | Assert.Throws(() => dictionary.CopyTo(null, 0)); 799 | // "TestICollection: FAILED. CopyTo didn't throw ANE when null Array is passed"); 800 | Assert.Throws(() => dictionary.CopyTo(new object[] { }, -1)); 801 | // "TestICollection: FAILED. CopyTo didn't throw AORE when negative index passed"); 802 | 803 | //add one item to the dictionary 804 | ((ConcurrentDictionary)dictionary).TryAdd(1, 1); 805 | Assert.Throws(() => dictionary.CopyTo(new object[] { }, 0)); 806 | // "TestICollection: FAILED. CopyTo didn't throw AE when the Array size is smaller than the dictionary count"); 807 | } 808 | 809 | [Test] 810 | public static void TestClear() 811 | { 812 | var dictionary = new ConcurrentDictionary(); 813 | for (int i = 0; i < 10; i++) 814 | dictionary.TryAdd(i, i); 815 | 816 | Assert.AreEqual(10, dictionary.Count); 817 | 818 | dictionary.Clear(); 819 | Assert.AreEqual(0, dictionary.Count); 820 | 821 | int item; 822 | Assert.False(dictionary.TryRemove(1, out item), "TestClear: FAILED. TryRemove succeeded after Clear"); 823 | Assert.True(dictionary.IsEmpty, "TestClear: FAILED. IsEmpty returned false after Clear"); 824 | } 825 | 826 | /* 827 | public static void TestTryUpdate() 828 | { 829 | var dictionary = new ConcurrentDictionary(); 830 | Assert.Throws( 831 | () => dictionary.TryUpdate(null, 0, 0)); 832 | // "TestTryUpdate: FAILED. TryUpdate didn't throw ANE when null key is passed"); 833 | 834 | for (int i = 0; i < 10; i++) 835 | dictionary.TryAdd(i.ToString(), i); 836 | 837 | for (int i = 0; i < 10; i++) 838 | { 839 | Assert.True(dictionary.TryUpdate(i.ToString(), i + 1, i), "TestTryUpdate: FAILED. TryUpdate failed!"); 840 | Assert.AreEqual(i + 1, dictionary[i.ToString()]); 841 | } 842 | 843 | //test TryUpdate concurrently 844 | dictionary.Clear(); 845 | for (int i = 0; i < 1000; i++) 846 | dictionary.TryAdd(i.ToString(), i); 847 | 848 | var mres = new ManualResetEventSlim(); 849 | Task[] tasks = new Task[10]; 850 | ThreadLocal updatedKeys = new ThreadLocal(true); 851 | for (int i = 0; i < tasks.Length; i++) 852 | { 853 | // We are creating the Task using TaskCreationOptions.LongRunning because... 854 | // there is no guarantee that the Task will be created on another thread. 855 | // There is also no guarantee that using this TaskCreationOption will force 856 | // it to be run on another thread. 857 | tasks[i] = Task.Factory.StartNew((obj) => 858 | { 859 | mres.Wait(); 860 | int index = (((int)obj) + 1) + 1000; 861 | updatedKeys.Value = new ThreadData(); 862 | updatedKeys.Value.ThreadIndex = index; 863 | 864 | for (int j = 0; j < dictionary.Count; j++) 865 | { 866 | if (dictionary.TryUpdate(j.ToString(), index, j)) 867 | { 868 | if (dictionary[j.ToString()] != index) 869 | { 870 | updatedKeys.Value.Succeeded = false; 871 | return; 872 | } 873 | updatedKeys.Value.Keys.Add(j.ToString()); 874 | } 875 | } 876 | }, i, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default); 877 | } 878 | 879 | mres.Set(); 880 | Task.WaitAll(tasks); 881 | 882 | int numberSucceeded = 0; 883 | int totalKeysUpdated = 0; 884 | foreach (var threadData in updatedKeys.Values) 885 | { 886 | totalKeysUpdated += threadData.Keys.Count; 887 | if (threadData.Succeeded) 888 | numberSucceeded++; 889 | } 890 | 891 | Assert.True(numberSucceeded == tasks.Length, "One or more threads failed!"); 892 | Assert.True(totalKeysUpdated == dictionary.Count, 893 | String.Format("TestTryUpdate: FAILED. The updated keys count doesn't match the dictionary count, expected {0}, actual {1}", dictionary.Count, totalKeysUpdated)); 894 | foreach (var value in updatedKeys.Values) 895 | { 896 | for (int i = 0; i < value.Keys.Count; i++) 897 | Assert.True(dictionary[value.Keys[i]] == value.ThreadIndex, 898 | String.Format("TestTryUpdate: FAILED. The updated value doesn't match the thread index, expected {0} actual {1}", value.ThreadIndex, dictionary[value.Keys[i]])); 899 | } 900 | 901 | //test TryUpdate with non atomic values (intPtr > 8) 902 | var dict = new ConcurrentDictionary(); 903 | dict.TryAdd(1, new Struct16(1, -1)); 904 | Assert.True(dict.TryUpdate(1, new Struct16(2, -2), new Struct16(1, -1)), "TestTryUpdate: FAILED. TryUpdate failed for non atomic values ( > 8 bytes)"); 905 | } 906 | */ 907 | 908 | #region Helper Classes and Methods 909 | 910 | private class ThreadData 911 | { 912 | public int ThreadIndex; 913 | public bool Succeeded = true; 914 | public List Keys = new List(); 915 | } 916 | 917 | private struct Struct16 : IEqualityComparer 918 | { 919 | public long L1, L2; 920 | public Struct16(long l1, long l2) 921 | { 922 | L1 = l1; 923 | L2 = l2; 924 | } 925 | 926 | public bool Equals(Struct16 x, Struct16 y) 927 | { 928 | return x.L1 == y.L1 && x.L2 == y.L2; 929 | } 930 | 931 | public int GetHashCode(Struct16 obj) 932 | { 933 | return (int)L1; 934 | } 935 | } 936 | 937 | #endregion 938 | } 939 | } 940 | -------------------------------------------------------------------------------- /core/ConcurrentDictionary/NetLegacySupport.ConcurrentDictionary.Release.md: -------------------------------------------------------------------------------- 1 | ## 1.1.1 (Released 2016/09/07) 2 | 3 | * Make an assembly strong-named. 4 | 5 | ## 1.1.0 (Released 2015/12/10) 6 | 7 | * Set AssemblyVersion to 1.0.0 to make a compatible dll. 8 | 9 | ## 1.0.2 (Released 2015/09/21) 10 | 11 | * Initial Release 12 | -------------------------------------------------------------------------------- /core/ConcurrentDictionary/NetLegacySupport.ConcurrentDictionary.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | @project@ 5 | @project@@title@ 6 | @build.number@ 7 | Microsoft 8 | Esun Kim 9 | System.ConcurrentDictionary for .NET Framework 2.0, 3.5. This is a backport from .NET Core. 10 | https://github.com/SaladLab/NetLegacySupport 11 | https://raw.githubusercontent.com/SaladLab/NetLegacySupport/master/LICENSE 12 | false 13 | @releaseNotes@ 14 | .net framework legacy support concurrent dictionary 15 | @dependencies@ 16 | @references@ 17 | 18 | 19 | -------------------------------------------------------------------------------- /core/ConcurrentDictionary/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("NetLegacySupport.ConcurrentDictionary")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("SaladLab")] 12 | [assembly: AssemblyProduct("NetLegacySupport.ConcurrentDictionary")] 13 | [assembly: AssemblyCopyright("Copyright © 2016 SaladLab")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("2a250c8c-f6c2-48ab-bbb5-cec1f2b7ce56")] 24 | -------------------------------------------------------------------------------- /core/ConcurrentDictionary/Properties/AssemblyInfoGenerated.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System.Reflection; 3 | 4 | [assembly: AssemblyVersionAttribute("1.0.0")] 5 | [assembly: AssemblyFileVersionAttribute("1.1.1")] 6 | [assembly: AssemblyInformationalVersionAttribute("1.1.1")] 7 | namespace System { 8 | internal static class AssemblyVersionInformation { 9 | internal const string Version = "1.0.0"; 10 | internal const string InformationalVersion = "1.1.1"; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /core/ConcurrentDictionary/System/Collections/Concurrent/FrameworkTraits.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | 4 | #if NET20 || NET35 5 | 6 | namespace FrameworkTraits 7 | { 8 | internal static class Volatile 9 | { 10 | public static T Read(ref T location) where T : class 11 | { 12 | // 13 | // The VM will replace this with a more efficient implementation. 14 | // 15 | var value = location; 16 | Thread.MemoryBarrier(); 17 | return value; 18 | } 19 | 20 | public static void Write(ref T location, T value) where T : class 21 | { 22 | // 23 | // The VM will replace this with a more efficient implementation. 24 | // 25 | Thread.MemoryBarrier(); 26 | location = value; 27 | } 28 | } 29 | 30 | internal static class PlatformHelper 31 | { 32 | public static int ProcessorCount 33 | { 34 | get { return Environment.ProcessorCount; } 35 | } 36 | } 37 | 38 | internal static class Monitor 39 | { 40 | public static void Enter(Object obj, ref bool lockTaken) 41 | { 42 | if (lockTaken) 43 | throw new ArgumentException("Argument must be initialized to false", "lockTaken"); 44 | 45 | System.Threading.Monitor.Enter(obj); 46 | lockTaken = true; 47 | } 48 | } 49 | } 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /core/Tuple.Net20.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Tuple.Net20.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("SaladLab")] 12 | [assembly: AssemblyProduct("Tuple.Net20.Tests")] 13 | [assembly: AssemblyCopyright("Copyright © 2016 SaladLab")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("15522d4f-0a13-4ae1-94b8-ae99b0d0847e")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /core/Tuple.Net20.Tests/Tuple.Net20.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {15522D4F-0A13-4AE1-94B8-AE99B0D0847E} 8 | Library 9 | Properties 10 | System 11 | NetLegacySupport.Tuple.Tests 12 | v2.0 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE;NET20 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE;NET20 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\..\packages\NUnit.3.0.1\lib\net20\nunit.framework.dll 35 | True 36 | 37 | 38 | 39 | 40 | 41 | TestTuple.cs 42 | 43 | 44 | 45 | 46 | 47 | {5545b95d-c742-4c8b-8a4d-70b548050547} 48 | Tuple.Net20 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 65 | -------------------------------------------------------------------------------- /core/Tuple.Net20.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /core/Tuple.Net20/Tuple.Net20.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {5545B95D-C742-4C8B-8A4D-70B548050547} 8 | Library 9 | Properties 10 | System 11 | NetLegacySupport.Tuple 12 | v2.0 13 | 512 14 | true 15 | ..\..\NetLegacySupport.snk 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | TRACE;DEBUG;NET20 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE;NET20 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | Properties\AssemblyInfo.cs 40 | 41 | 42 | Properties\AssemblyInfoGenerated.cs 43 | 44 | 45 | System\Collections\IStructuralComparable.cs 46 | 47 | 48 | System\Collections\IStructuralEquatable.cs 49 | 50 | 51 | System\Tuple.cs 52 | 53 | 54 | 55 | 62 | -------------------------------------------------------------------------------- /core/Tuple.Net35.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Tuple.Net35.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("SaladLab")] 12 | [assembly: AssemblyProduct("Tuple.Net35.Tests")] 13 | [assembly: AssemblyCopyright("Copyright © 2016 SaladLab")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("461a55b6-5db1-44c3-bd71-d286a356c0a8")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /core/Tuple.Net35.Tests/Tuple.Net35.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {461A55B6-5DB1-44C3-BD71-D286A356C0A8} 8 | Library 9 | Properties 10 | System 11 | NetLegacySupport.Tuple.Tests 12 | v3.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE;NET35 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE;NET35 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\..\packages\NUnit.3.0.1\lib\net20\nunit.framework.dll 35 | True 36 | 37 | 38 | 39 | 40 | 41 | TestTuple.cs 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | {d434bddd-1eda-4212-b6d6-52dd80a08969} 51 | Tuple.Net35 52 | 53 | 54 | 55 | 56 | 57 | 58 | 65 | -------------------------------------------------------------------------------- /core/Tuple.Net35.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /core/Tuple.Net35/Tuple.Net35.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {D434BDDD-1EDA-4212-B6D6-52DD80A08969} 8 | Library 9 | Properties 10 | System 11 | NetLegacySupport.Tuple 12 | v3.5 13 | 512 14 | true 15 | ..\..\NetLegacySupport.snk 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE;NET35 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE;NET35 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | Properties\AssemblyInfo.cs 40 | 41 | 42 | Properties\AssemblyInfoGenerated.cs 43 | 44 | 45 | System\Collections\IStructuralComparable.cs 46 | 47 | 48 | System\Collections\IStructuralEquatable.cs 49 | 50 | 51 | System\Tuple.cs 52 | 53 | 54 | 55 | 62 | -------------------------------------------------------------------------------- /core/Tuple.Net40.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Tuple.Net40.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("SaladLab")] 12 | [assembly: AssemblyProduct("Tuple.Net40.Tests")] 13 | [assembly: AssemblyCopyright("Copyright © 2016 SaladLab")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("10bef5b7-7f3f-4a5c-8b43-b1f2c6637af9")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /core/Tuple.Net40.Tests/Tuple.Net40.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {10BEF5B7-7F3F-4A5C-8B43-B1F2C6637AF9} 8 | Library 9 | Properties 10 | System 11 | NetLegacySupport.Tuple.Tests 12 | v4.0 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE;NET40 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE;NET40 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\..\packages\NUnit.3.0.1\lib\net40\nunit.framework.dll 35 | True 36 | 37 | 38 | 39 | 40 | 41 | TestTuple.cs 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | {df53f862-9220-4c36-9973-b7e899ea4596} 51 | Tuple.Net40 52 | 53 | 54 | 55 | 62 | -------------------------------------------------------------------------------- /core/Tuple.Net40.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /core/Tuple.Net40/Tuple.Net40.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {DF53F862-9220-4C36-9973-B7E899EA4596} 8 | Library 9 | Properties 10 | System 11 | NetLegacySupport.Tuple 12 | v4.0 13 | 512 14 | true 15 | ..\..\NetLegacySupport.snk 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE;NET40 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE;NET40 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | Properties\AssemblyInfo.cs 40 | 41 | 42 | Properties\AssemblyInfoGenerated.cs 43 | 44 | 45 | System\Collections\IStructuralComparable.cs 46 | 47 | 48 | System\Collections\IStructuralEquatable.cs 49 | 50 | 51 | System\Tuple.cs 52 | 53 | 54 | 55 | 62 | -------------------------------------------------------------------------------- /core/Tuple/NetLegacySupport.Tuple.Release.md: -------------------------------------------------------------------------------- 1 | ## 1.1.1 (Released 2016/09/07) 2 | 3 | * Make an assembly strong-named. 4 | 5 | ## 1.1.0 (Released 2015/12/10) 6 | 7 | * Set AssemblyVersion to 1.0.0 to make a compatible dll. 8 | 9 | ## 1.0.2 (Released 2015/09/21) 10 | 11 | * Initial Release 12 | -------------------------------------------------------------------------------- /core/Tuple/NetLegacySupport.Tuple.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | @project@ 5 | @project@@title@ 6 | @build.number@ 7 | Microsoft 8 | Esun Kim 9 | System.Tuple for .NET Framework 2.0, 3.5. This is a backport from .NET Core. 10 | https://github.com/SaladLab/NetLegacySupport 11 | https://raw.githubusercontent.com/SaladLab/NetLegacySupport/master/LICENSE 12 | false 13 | @releaseNotes@ 14 | .net framework legacy support tuple 15 | @dependencies@ 16 | @references@ 17 | 18 | 19 | -------------------------------------------------------------------------------- /core/Tuple/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("NetLegacySupport.Tuple")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("SaladLab")] 12 | [assembly: AssemblyProduct("NetLegacySupport.Tuple")] 13 | [assembly: AssemblyCopyright("Copyright © 2016 SaladLab")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("791c96a3-6394-4a5e-b89f-97688be5cb6b")] 24 | -------------------------------------------------------------------------------- /core/Tuple/Properties/AssemblyInfoGenerated.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System.Reflection; 3 | 4 | [assembly: AssemblyVersionAttribute("1.0.0")] 5 | [assembly: AssemblyFileVersionAttribute("1.1.1")] 6 | [assembly: AssemblyInformationalVersionAttribute("1.1.1")] 7 | namespace System { 8 | internal static class AssemblyVersionInformation { 9 | internal const string Version = "1.0.0"; 10 | internal const string InformationalVersion = "1.1.1"; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /core/Tuple/System/Collections/IStructuralComparable.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | #if NET20 || NET35 5 | 6 | using System; 7 | 8 | namespace System.Collections { 9 | 10 | public interface IStructuralComparable { 11 | Int32 CompareTo(Object other, IComparer comparer); 12 | } 13 | } 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /core/Tuple/System/Collections/IStructuralEquatable.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | #if NET20 || NET35 5 | 6 | namespace System.Collections { 7 | 8 | public interface IStructuralEquatable { 9 | Boolean Equals(Object other, IEqualityComparer comparer); 10 | int GetHashCode(IEqualityComparer comparer); 11 | } 12 | } 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /core/Tuple/System/Tuple.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | #if NET20 || NET35 5 | 6 | using System; 7 | using System.Text; 8 | using System.Collections; 9 | using System.Collections.Generic; 10 | using System.Diagnostics; 11 | // using System.Diagnostics.Contracts; 12 | 13 | namespace System { 14 | 15 | /// 16 | /// Helper so we can call some tuple methods recursively without knowing the underlying types. 17 | /// 18 | internal interface ITuple { 19 | string ToString(StringBuilder sb); 20 | int GetHashCode(IEqualityComparer comparer); 21 | int Size { get; } 22 | 23 | } 24 | 25 | public static class Tuple { 26 | public static Tuple Create(T1 item1) { 27 | return new Tuple(item1); 28 | } 29 | 30 | public static Tuple Create(T1 item1, T2 item2) { 31 | return new Tuple(item1, item2); 32 | } 33 | 34 | public static Tuple Create(T1 item1, T2 item2, T3 item3) { 35 | return new Tuple(item1, item2, item3); 36 | } 37 | 38 | public static Tuple Create(T1 item1, T2 item2, T3 item3, T4 item4) { 39 | return new Tuple(item1, item2, item3, item4); 40 | } 41 | 42 | public static Tuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) { 43 | return new Tuple(item1, item2, item3, item4, item5); 44 | } 45 | 46 | public static Tuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) { 47 | return new Tuple(item1, item2, item3, item4, item5, item6); 48 | } 49 | 50 | public static Tuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) { 51 | return new Tuple(item1, item2, item3, item4, item5, item6, item7); 52 | } 53 | 54 | public static Tuple> Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8) { 55 | return new Tuple>(item1, item2, item3, item4, item5, item6, item7, new Tuple(item8)); 56 | } 57 | 58 | // From System.Web.Util.HashCodeCombiner 59 | internal static int CombineHashCodes(int h1, int h2) { 60 | return (((h1 << 5) + h1) ^ h2); 61 | } 62 | 63 | internal static int CombineHashCodes(int h1, int h2, int h3) { 64 | return CombineHashCodes(CombineHashCodes(h1, h2), h3); 65 | } 66 | 67 | internal static int CombineHashCodes(int h1, int h2, int h3, int h4) { 68 | return CombineHashCodes(CombineHashCodes(h1, h2), CombineHashCodes(h3, h4)); 69 | } 70 | 71 | internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5) { 72 | return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), h5); 73 | } 74 | 75 | internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6) { 76 | return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), CombineHashCodes(h5, h6)); 77 | } 78 | 79 | internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7) { 80 | return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), CombineHashCodes(h5, h6, h7)); 81 | } 82 | 83 | internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8) { 84 | return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), CombineHashCodes(h5, h6, h7, h8)); 85 | } 86 | } 87 | 88 | [Serializable] 89 | public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITuple { 90 | 91 | private readonly T1 m_Item1; 92 | 93 | public T1 Item1 { get { return m_Item1; } } 94 | 95 | public Tuple(T1 item1) { 96 | m_Item1 = item1; 97 | } 98 | 99 | public override Boolean Equals(Object obj) { 100 | return ((IStructuralEquatable) this).Equals(obj, EqualityComparer.Default); 101 | } 102 | 103 | Boolean IStructuralEquatable.Equals(Object other, IEqualityComparer comparer) { 104 | if (other == null) return false; 105 | 106 | Tuple objTuple = other as Tuple; 107 | 108 | if (objTuple == null) { 109 | return false; 110 | } 111 | 112 | return comparer.Equals(m_Item1, objTuple.m_Item1); 113 | } 114 | 115 | Int32 IComparable.CompareTo(Object obj) { 116 | return ((IStructuralComparable) this).CompareTo(obj, Comparer.Default); 117 | } 118 | 119 | Int32 IStructuralComparable.CompareTo(Object other, IComparer comparer) { 120 | if (other == null) return 1; 121 | 122 | Tuple objTuple = other as Tuple; 123 | 124 | if (objTuple == null) { 125 | throw new ArgumentException(string.Format("Argument must be of type {0}.", this.GetType().ToString()), "other"); 126 | } 127 | 128 | return comparer.Compare(m_Item1, objTuple.m_Item1); 129 | } 130 | 131 | public override int GetHashCode() { 132 | return ((IStructuralEquatable) this).GetHashCode(EqualityComparer.Default); 133 | } 134 | 135 | Int32 IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { 136 | return comparer.GetHashCode(m_Item1); 137 | } 138 | 139 | Int32 ITuple.GetHashCode(IEqualityComparer comparer) { 140 | return ((IStructuralEquatable) this).GetHashCode(comparer); 141 | } 142 | public override string ToString() { 143 | StringBuilder sb = new StringBuilder(); 144 | sb.Append("("); 145 | return ((ITuple)this).ToString(sb); 146 | } 147 | 148 | string ITuple.ToString(StringBuilder sb) { 149 | sb.Append(m_Item1); 150 | sb.Append(")"); 151 | return sb.ToString(); 152 | } 153 | 154 | int ITuple.Size { 155 | get { 156 | return 1; 157 | } 158 | } 159 | } 160 | 161 | [Serializable] 162 | public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITuple { 163 | 164 | private readonly T1 m_Item1; 165 | private readonly T2 m_Item2; 166 | 167 | public T1 Item1 { get { return m_Item1; } } 168 | public T2 Item2 { get { return m_Item2; } } 169 | 170 | public Tuple(T1 item1, T2 item2) { 171 | m_Item1 = item1; 172 | m_Item2 = item2; 173 | } 174 | 175 | public override Boolean Equals(Object obj) { 176 | return ((IStructuralEquatable) this).Equals(obj, EqualityComparer.Default);; 177 | } 178 | 179 | Boolean IStructuralEquatable.Equals(Object other, IEqualityComparer comparer) { 180 | if (other == null) return false; 181 | 182 | Tuple objTuple = other as Tuple; 183 | 184 | if (objTuple == null) { 185 | return false; 186 | } 187 | 188 | return comparer.Equals(m_Item1, objTuple.m_Item1) && comparer.Equals(m_Item2, objTuple.m_Item2); 189 | } 190 | 191 | Int32 IComparable.CompareTo(Object obj) { 192 | return ((IStructuralComparable) this).CompareTo(obj, Comparer.Default); 193 | } 194 | 195 | Int32 IStructuralComparable.CompareTo(Object other, IComparer comparer) { 196 | if (other == null) return 1; 197 | 198 | Tuple objTuple = other as Tuple; 199 | 200 | if (objTuple == null) { 201 | throw new ArgumentException(string.Format("Argument must be of type {0}.", this.GetType().ToString()), "other"); 202 | } 203 | 204 | int c = 0; 205 | 206 | c = comparer.Compare(m_Item1, objTuple.m_Item1); 207 | 208 | if (c != 0) return c; 209 | 210 | return comparer.Compare(m_Item2, objTuple.m_Item2); 211 | } 212 | 213 | public override int GetHashCode() { 214 | return ((IStructuralEquatable) this).GetHashCode(EqualityComparer.Default); 215 | } 216 | 217 | Int32 IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { 218 | return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item1), comparer.GetHashCode(m_Item2)); 219 | } 220 | 221 | Int32 ITuple.GetHashCode(IEqualityComparer comparer) { 222 | return ((IStructuralEquatable) this).GetHashCode(comparer); 223 | } 224 | public override string ToString() { 225 | StringBuilder sb = new StringBuilder(); 226 | sb.Append("("); 227 | return ((ITuple)this).ToString(sb); 228 | } 229 | 230 | string ITuple.ToString(StringBuilder sb) { 231 | sb.Append(m_Item1); 232 | sb.Append(", "); 233 | sb.Append(m_Item2); 234 | sb.Append(")"); 235 | return sb.ToString(); 236 | } 237 | 238 | int ITuple.Size { 239 | get { 240 | return 2; 241 | } 242 | } 243 | } 244 | 245 | [Serializable] 246 | public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITuple { 247 | 248 | private readonly T1 m_Item1; 249 | private readonly T2 m_Item2; 250 | private readonly T3 m_Item3; 251 | 252 | public T1 Item1 { get { return m_Item1; } } 253 | public T2 Item2 { get { return m_Item2; } } 254 | public T3 Item3 { get { return m_Item3; } } 255 | 256 | public Tuple(T1 item1, T2 item2, T3 item3) { 257 | m_Item1 = item1; 258 | m_Item2 = item2; 259 | m_Item3 = item3; 260 | } 261 | 262 | public override Boolean Equals(Object obj) { 263 | return ((IStructuralEquatable) this).Equals(obj, EqualityComparer.Default);; 264 | } 265 | 266 | Boolean IStructuralEquatable.Equals(Object other, IEqualityComparer comparer) { 267 | if (other == null) return false; 268 | 269 | Tuple objTuple = other as Tuple; 270 | 271 | if (objTuple == null) { 272 | return false; 273 | } 274 | 275 | return comparer.Equals(m_Item1, objTuple.m_Item1) && comparer.Equals(m_Item2, objTuple.m_Item2) && comparer.Equals(m_Item3, objTuple.m_Item3); 276 | } 277 | 278 | Int32 IComparable.CompareTo(Object obj) { 279 | return ((IStructuralComparable) this).CompareTo(obj, Comparer.Default); 280 | } 281 | 282 | Int32 IStructuralComparable.CompareTo(Object other, IComparer comparer) { 283 | if (other == null) return 1; 284 | 285 | Tuple objTuple = other as Tuple; 286 | 287 | if (objTuple == null) { 288 | throw new ArgumentException(string.Format("Argument must be of type {0}.", this.GetType().ToString()), "other"); 289 | } 290 | 291 | int c = 0; 292 | 293 | c = comparer.Compare(m_Item1, objTuple.m_Item1); 294 | 295 | if (c != 0) return c; 296 | 297 | c = comparer.Compare(m_Item2, objTuple.m_Item2); 298 | 299 | if (c != 0) return c; 300 | 301 | return comparer.Compare(m_Item3, objTuple.m_Item3); 302 | } 303 | 304 | public override int GetHashCode() { 305 | return ((IStructuralEquatable) this).GetHashCode(EqualityComparer.Default); 306 | } 307 | 308 | Int32 IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { 309 | return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item1), comparer.GetHashCode(m_Item2), comparer.GetHashCode(m_Item3)); 310 | } 311 | 312 | Int32 ITuple.GetHashCode(IEqualityComparer comparer) { 313 | return ((IStructuralEquatable) this).GetHashCode(comparer); 314 | } 315 | public override string ToString() { 316 | StringBuilder sb = new StringBuilder(); 317 | sb.Append("("); 318 | return ((ITuple)this).ToString(sb); 319 | } 320 | 321 | string ITuple.ToString(StringBuilder sb) { 322 | sb.Append(m_Item1); 323 | sb.Append(", "); 324 | sb.Append(m_Item2); 325 | sb.Append(", "); 326 | sb.Append(m_Item3); 327 | sb.Append(")"); 328 | return sb.ToString(); 329 | } 330 | 331 | int ITuple.Size { 332 | get { 333 | return 3; 334 | } 335 | } 336 | } 337 | 338 | [Serializable] 339 | public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITuple { 340 | 341 | private readonly T1 m_Item1; 342 | private readonly T2 m_Item2; 343 | private readonly T3 m_Item3; 344 | private readonly T4 m_Item4; 345 | 346 | public T1 Item1 { get { return m_Item1; } } 347 | public T2 Item2 { get { return m_Item2; } } 348 | public T3 Item3 { get { return m_Item3; } } 349 | public T4 Item4 { get { return m_Item4; } } 350 | 351 | public Tuple(T1 item1, T2 item2, T3 item3, T4 item4) { 352 | m_Item1 = item1; 353 | m_Item2 = item2; 354 | m_Item3 = item3; 355 | m_Item4 = item4; 356 | } 357 | 358 | public override Boolean Equals(Object obj) { 359 | return ((IStructuralEquatable) this).Equals(obj, EqualityComparer.Default);; 360 | } 361 | 362 | Boolean IStructuralEquatable.Equals(Object other, IEqualityComparer comparer) { 363 | if (other == null) return false; 364 | 365 | Tuple objTuple = other as Tuple; 366 | 367 | if (objTuple == null) { 368 | return false; 369 | } 370 | 371 | return comparer.Equals(m_Item1, objTuple.m_Item1) && comparer.Equals(m_Item2, objTuple.m_Item2) && comparer.Equals(m_Item3, objTuple.m_Item3) && comparer.Equals(m_Item4, objTuple.m_Item4); 372 | } 373 | 374 | Int32 IComparable.CompareTo(Object obj) { 375 | return ((IStructuralComparable) this).CompareTo(obj, Comparer.Default); 376 | } 377 | 378 | Int32 IStructuralComparable.CompareTo(Object other, IComparer comparer) { 379 | if (other == null) return 1; 380 | 381 | Tuple objTuple = other as Tuple; 382 | 383 | if (objTuple == null) { 384 | throw new ArgumentException(string.Format("Argument must be of type {0}.", this.GetType().ToString()), "other"); 385 | } 386 | 387 | int c = 0; 388 | 389 | c = comparer.Compare(m_Item1, objTuple.m_Item1); 390 | 391 | if (c != 0) return c; 392 | 393 | c = comparer.Compare(m_Item2, objTuple.m_Item2); 394 | 395 | if (c != 0) return c; 396 | 397 | c = comparer.Compare(m_Item3, objTuple.m_Item3); 398 | 399 | if (c != 0) return c; 400 | 401 | return comparer.Compare(m_Item4, objTuple.m_Item4); 402 | } 403 | 404 | public override int GetHashCode() { 405 | return ((IStructuralEquatable) this).GetHashCode(EqualityComparer.Default); 406 | } 407 | 408 | Int32 IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { 409 | return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item1), comparer.GetHashCode(m_Item2), comparer.GetHashCode(m_Item3), comparer.GetHashCode(m_Item4)); 410 | } 411 | 412 | Int32 ITuple.GetHashCode(IEqualityComparer comparer) { 413 | return ((IStructuralEquatable) this).GetHashCode(comparer); 414 | } 415 | public override string ToString() { 416 | StringBuilder sb = new StringBuilder(); 417 | sb.Append("("); 418 | return ((ITuple)this).ToString(sb); 419 | } 420 | 421 | string ITuple.ToString(StringBuilder sb) { 422 | sb.Append(m_Item1); 423 | sb.Append(", "); 424 | sb.Append(m_Item2); 425 | sb.Append(", "); 426 | sb.Append(m_Item3); 427 | sb.Append(", "); 428 | sb.Append(m_Item4); 429 | sb.Append(")"); 430 | return sb.ToString(); 431 | } 432 | 433 | int ITuple.Size { 434 | get { 435 | return 4; 436 | } 437 | } 438 | } 439 | 440 | [Serializable] 441 | public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITuple { 442 | 443 | private readonly T1 m_Item1; 444 | private readonly T2 m_Item2; 445 | private readonly T3 m_Item3; 446 | private readonly T4 m_Item4; 447 | private readonly T5 m_Item5; 448 | 449 | public T1 Item1 { get { return m_Item1; } } 450 | public T2 Item2 { get { return m_Item2; } } 451 | public T3 Item3 { get { return m_Item3; } } 452 | public T4 Item4 { get { return m_Item4; } } 453 | public T5 Item5 { get { return m_Item5; } } 454 | 455 | public Tuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) { 456 | m_Item1 = item1; 457 | m_Item2 = item2; 458 | m_Item3 = item3; 459 | m_Item4 = item4; 460 | m_Item5 = item5; 461 | } 462 | 463 | public override Boolean Equals(Object obj) { 464 | return ((IStructuralEquatable) this).Equals(obj, EqualityComparer.Default);; 465 | } 466 | 467 | Boolean IStructuralEquatable.Equals(Object other, IEqualityComparer comparer) { 468 | if (other == null) return false; 469 | 470 | Tuple objTuple = other as Tuple; 471 | 472 | if (objTuple == null) { 473 | return false; 474 | } 475 | 476 | return comparer.Equals(m_Item1, objTuple.m_Item1) && comparer.Equals(m_Item2, objTuple.m_Item2) && comparer.Equals(m_Item3, objTuple.m_Item3) && comparer.Equals(m_Item4, objTuple.m_Item4) && comparer.Equals(m_Item5, objTuple.m_Item5); 477 | } 478 | 479 | Int32 IComparable.CompareTo(Object obj) { 480 | return ((IStructuralComparable) this).CompareTo(obj, Comparer.Default); 481 | } 482 | 483 | Int32 IStructuralComparable.CompareTo(Object other, IComparer comparer) { 484 | if (other == null) return 1; 485 | 486 | Tuple objTuple = other as Tuple; 487 | 488 | if (objTuple == null) { 489 | throw new ArgumentException(string.Format("Argument must be of type {0}.", this.GetType().ToString()), "other"); 490 | } 491 | 492 | int c = 0; 493 | 494 | c = comparer.Compare(m_Item1, objTuple.m_Item1); 495 | 496 | if (c != 0) return c; 497 | 498 | c = comparer.Compare(m_Item2, objTuple.m_Item2); 499 | 500 | if (c != 0) return c; 501 | 502 | c = comparer.Compare(m_Item3, objTuple.m_Item3); 503 | 504 | if (c != 0) return c; 505 | 506 | c = comparer.Compare(m_Item4, objTuple.m_Item4); 507 | 508 | if (c != 0) return c; 509 | 510 | return comparer.Compare(m_Item5, objTuple.m_Item5); 511 | } 512 | 513 | public override int GetHashCode() { 514 | return ((IStructuralEquatable) this).GetHashCode(EqualityComparer.Default); 515 | } 516 | 517 | Int32 IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { 518 | return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item1), comparer.GetHashCode(m_Item2), comparer.GetHashCode(m_Item3), comparer.GetHashCode(m_Item4), comparer.GetHashCode(m_Item5)); 519 | } 520 | 521 | Int32 ITuple.GetHashCode(IEqualityComparer comparer) { 522 | return ((IStructuralEquatable) this).GetHashCode(comparer); 523 | } 524 | public override string ToString() { 525 | StringBuilder sb = new StringBuilder(); 526 | sb.Append("("); 527 | return ((ITuple)this).ToString(sb); 528 | } 529 | 530 | string ITuple.ToString(StringBuilder sb) { 531 | sb.Append(m_Item1); 532 | sb.Append(", "); 533 | sb.Append(m_Item2); 534 | sb.Append(", "); 535 | sb.Append(m_Item3); 536 | sb.Append(", "); 537 | sb.Append(m_Item4); 538 | sb.Append(", "); 539 | sb.Append(m_Item5); 540 | sb.Append(")"); 541 | return sb.ToString(); 542 | } 543 | 544 | int ITuple.Size { 545 | get { 546 | return 5; 547 | } 548 | } 549 | } 550 | 551 | [Serializable] 552 | public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITuple { 553 | 554 | private readonly T1 m_Item1; 555 | private readonly T2 m_Item2; 556 | private readonly T3 m_Item3; 557 | private readonly T4 m_Item4; 558 | private readonly T5 m_Item5; 559 | private readonly T6 m_Item6; 560 | 561 | public T1 Item1 { get { return m_Item1; } } 562 | public T2 Item2 { get { return m_Item2; } } 563 | public T3 Item3 { get { return m_Item3; } } 564 | public T4 Item4 { get { return m_Item4; } } 565 | public T5 Item5 { get { return m_Item5; } } 566 | public T6 Item6 { get { return m_Item6; } } 567 | 568 | public Tuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) { 569 | m_Item1 = item1; 570 | m_Item2 = item2; 571 | m_Item3 = item3; 572 | m_Item4 = item4; 573 | m_Item5 = item5; 574 | m_Item6 = item6; 575 | } 576 | 577 | public override Boolean Equals(Object obj) { 578 | return ((IStructuralEquatable) this).Equals(obj, EqualityComparer.Default);; 579 | } 580 | 581 | Boolean IStructuralEquatable.Equals(Object other, IEqualityComparer comparer) { 582 | if (other == null) return false; 583 | 584 | Tuple objTuple = other as Tuple; 585 | 586 | if (objTuple == null) { 587 | return false; 588 | } 589 | 590 | return comparer.Equals(m_Item1, objTuple.m_Item1) && comparer.Equals(m_Item2, objTuple.m_Item2) && comparer.Equals(m_Item3, objTuple.m_Item3) && comparer.Equals(m_Item4, objTuple.m_Item4) && comparer.Equals(m_Item5, objTuple.m_Item5) && comparer.Equals(m_Item6, objTuple.m_Item6); 591 | } 592 | 593 | Int32 IComparable.CompareTo(Object obj) { 594 | return ((IStructuralComparable) this).CompareTo(obj, Comparer.Default); 595 | } 596 | 597 | Int32 IStructuralComparable.CompareTo(Object other, IComparer comparer) { 598 | if (other == null) return 1; 599 | 600 | Tuple objTuple = other as Tuple; 601 | 602 | if (objTuple == null) { 603 | throw new ArgumentException(string.Format("Argument must be of type {0}.", this.GetType().ToString()), "other"); 604 | } 605 | 606 | int c = 0; 607 | 608 | c = comparer.Compare(m_Item1, objTuple.m_Item1); 609 | 610 | if (c != 0) return c; 611 | 612 | c = comparer.Compare(m_Item2, objTuple.m_Item2); 613 | 614 | if (c != 0) return c; 615 | 616 | c = comparer.Compare(m_Item3, objTuple.m_Item3); 617 | 618 | if (c != 0) return c; 619 | 620 | c = comparer.Compare(m_Item4, objTuple.m_Item4); 621 | 622 | if (c != 0) return c; 623 | 624 | c = comparer.Compare(m_Item5, objTuple.m_Item5); 625 | 626 | if (c != 0) return c; 627 | 628 | return comparer.Compare(m_Item6, objTuple.m_Item6); 629 | } 630 | 631 | public override int GetHashCode() { 632 | return ((IStructuralEquatable) this).GetHashCode(EqualityComparer.Default); 633 | } 634 | 635 | Int32 IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { 636 | return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item1), comparer.GetHashCode(m_Item2), comparer.GetHashCode(m_Item3), comparer.GetHashCode(m_Item4), comparer.GetHashCode(m_Item5), comparer.GetHashCode(m_Item6)); 637 | } 638 | 639 | Int32 ITuple.GetHashCode(IEqualityComparer comparer) { 640 | return ((IStructuralEquatable) this).GetHashCode(comparer); 641 | } 642 | public override string ToString() { 643 | StringBuilder sb = new StringBuilder(); 644 | sb.Append("("); 645 | return ((ITuple)this).ToString(sb); 646 | } 647 | 648 | string ITuple.ToString(StringBuilder sb) { 649 | sb.Append(m_Item1); 650 | sb.Append(", "); 651 | sb.Append(m_Item2); 652 | sb.Append(", "); 653 | sb.Append(m_Item3); 654 | sb.Append(", "); 655 | sb.Append(m_Item4); 656 | sb.Append(", "); 657 | sb.Append(m_Item5); 658 | sb.Append(", "); 659 | sb.Append(m_Item6); 660 | sb.Append(")"); 661 | return sb.ToString(); 662 | } 663 | 664 | int ITuple.Size { 665 | get { 666 | return 6; 667 | } 668 | } 669 | } 670 | 671 | [Serializable] 672 | public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITuple { 673 | 674 | private readonly T1 m_Item1; 675 | private readonly T2 m_Item2; 676 | private readonly T3 m_Item3; 677 | private readonly T4 m_Item4; 678 | private readonly T5 m_Item5; 679 | private readonly T6 m_Item6; 680 | private readonly T7 m_Item7; 681 | 682 | public T1 Item1 { get { return m_Item1; } } 683 | public T2 Item2 { get { return m_Item2; } } 684 | public T3 Item3 { get { return m_Item3; } } 685 | public T4 Item4 { get { return m_Item4; } } 686 | public T5 Item5 { get { return m_Item5; } } 687 | public T6 Item6 { get { return m_Item6; } } 688 | public T7 Item7 { get { return m_Item7; } } 689 | 690 | public Tuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) { 691 | m_Item1 = item1; 692 | m_Item2 = item2; 693 | m_Item3 = item3; 694 | m_Item4 = item4; 695 | m_Item5 = item5; 696 | m_Item6 = item6; 697 | m_Item7 = item7; 698 | } 699 | 700 | public override Boolean Equals(Object obj) { 701 | return ((IStructuralEquatable) this).Equals(obj, EqualityComparer.Default);; 702 | } 703 | 704 | Boolean IStructuralEquatable.Equals(Object other, IEqualityComparer comparer) { 705 | if (other == null) return false; 706 | 707 | Tuple objTuple = other as Tuple; 708 | 709 | if (objTuple == null) { 710 | return false; 711 | } 712 | 713 | return comparer.Equals(m_Item1, objTuple.m_Item1) && comparer.Equals(m_Item2, objTuple.m_Item2) && comparer.Equals(m_Item3, objTuple.m_Item3) && comparer.Equals(m_Item4, objTuple.m_Item4) && comparer.Equals(m_Item5, objTuple.m_Item5) && comparer.Equals(m_Item6, objTuple.m_Item6) && comparer.Equals(m_Item7, objTuple.m_Item7); 714 | } 715 | 716 | Int32 IComparable.CompareTo(Object obj) { 717 | return ((IStructuralComparable) this).CompareTo(obj, Comparer.Default); 718 | } 719 | 720 | Int32 IStructuralComparable.CompareTo(Object other, IComparer comparer) { 721 | if (other == null) return 1; 722 | 723 | Tuple objTuple = other as Tuple; 724 | 725 | if (objTuple == null) { 726 | throw new ArgumentException(string.Format("Argument must be of type {0}.", this.GetType().ToString()), "other"); 727 | } 728 | 729 | int c = 0; 730 | 731 | c = comparer.Compare(m_Item1, objTuple.m_Item1); 732 | 733 | if (c != 0) return c; 734 | 735 | c = comparer.Compare(m_Item2, objTuple.m_Item2); 736 | 737 | if (c != 0) return c; 738 | 739 | c = comparer.Compare(m_Item3, objTuple.m_Item3); 740 | 741 | if (c != 0) return c; 742 | 743 | c = comparer.Compare(m_Item4, objTuple.m_Item4); 744 | 745 | if (c != 0) return c; 746 | 747 | c = comparer.Compare(m_Item5, objTuple.m_Item5); 748 | 749 | if (c != 0) return c; 750 | 751 | c = comparer.Compare(m_Item6, objTuple.m_Item6); 752 | 753 | if (c != 0) return c; 754 | 755 | return comparer.Compare(m_Item7, objTuple.m_Item7); 756 | } 757 | 758 | public override int GetHashCode() { 759 | return ((IStructuralEquatable) this).GetHashCode(EqualityComparer.Default); 760 | } 761 | 762 | Int32 IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { 763 | return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item1), comparer.GetHashCode(m_Item2), comparer.GetHashCode(m_Item3), comparer.GetHashCode(m_Item4), comparer.GetHashCode(m_Item5), comparer.GetHashCode(m_Item6), comparer.GetHashCode(m_Item7)); 764 | } 765 | 766 | Int32 ITuple.GetHashCode(IEqualityComparer comparer) { 767 | return ((IStructuralEquatable) this).GetHashCode(comparer); 768 | } 769 | public override string ToString() { 770 | StringBuilder sb = new StringBuilder(); 771 | sb.Append("("); 772 | return ((ITuple)this).ToString(sb); 773 | } 774 | 775 | string ITuple.ToString(StringBuilder sb) { 776 | sb.Append(m_Item1); 777 | sb.Append(", "); 778 | sb.Append(m_Item2); 779 | sb.Append(", "); 780 | sb.Append(m_Item3); 781 | sb.Append(", "); 782 | sb.Append(m_Item4); 783 | sb.Append(", "); 784 | sb.Append(m_Item5); 785 | sb.Append(", "); 786 | sb.Append(m_Item6); 787 | sb.Append(", "); 788 | sb.Append(m_Item7); 789 | sb.Append(")"); 790 | return sb.ToString(); 791 | } 792 | 793 | int ITuple.Size { 794 | get { 795 | return 7; 796 | } 797 | } 798 | } 799 | 800 | [Serializable] 801 | public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable, ITuple { 802 | 803 | private readonly T1 m_Item1; 804 | private readonly T2 m_Item2; 805 | private readonly T3 m_Item3; 806 | private readonly T4 m_Item4; 807 | private readonly T5 m_Item5; 808 | private readonly T6 m_Item6; 809 | private readonly T7 m_Item7; 810 | private readonly TRest m_Rest; 811 | 812 | public T1 Item1 { get { return m_Item1; } } 813 | public T2 Item2 { get { return m_Item2; } } 814 | public T3 Item3 { get { return m_Item3; } } 815 | public T4 Item4 { get { return m_Item4; } } 816 | public T5 Item5 { get { return m_Item5; } } 817 | public T6 Item6 { get { return m_Item6; } } 818 | public T7 Item7 { get { return m_Item7; } } 819 | public TRest Rest { get { return m_Rest; } } 820 | 821 | public Tuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) { 822 | if (!(rest is ITuple)) { 823 | throw new ArgumentException(string.Format("The last element of an eight element tuple must be a Tuple.")); 824 | } 825 | 826 | m_Item1 = item1; 827 | m_Item2 = item2; 828 | m_Item3 = item3; 829 | m_Item4 = item4; 830 | m_Item5 = item5; 831 | m_Item6 = item6; 832 | m_Item7 = item7; 833 | m_Rest = rest; 834 | } 835 | 836 | public override Boolean Equals(Object obj) { 837 | return ((IStructuralEquatable) this).Equals(obj, EqualityComparer.Default);; 838 | } 839 | 840 | Boolean IStructuralEquatable.Equals(Object other, IEqualityComparer comparer) { 841 | if (other == null) return false; 842 | 843 | Tuple objTuple = other as Tuple; 844 | 845 | if (objTuple == null) { 846 | return false; 847 | } 848 | 849 | return comparer.Equals(m_Item1, objTuple.m_Item1) && comparer.Equals(m_Item2, objTuple.m_Item2) && comparer.Equals(m_Item3, objTuple.m_Item3) && comparer.Equals(m_Item4, objTuple.m_Item4) && comparer.Equals(m_Item5, objTuple.m_Item5) && comparer.Equals(m_Item6, objTuple.m_Item6) && comparer.Equals(m_Item7, objTuple.m_Item7) && comparer.Equals(m_Rest, objTuple.m_Rest); 850 | } 851 | 852 | Int32 IComparable.CompareTo(Object obj) { 853 | return ((IStructuralComparable) this).CompareTo(obj, Comparer.Default); 854 | } 855 | 856 | Int32 IStructuralComparable.CompareTo(Object other, IComparer comparer) { 857 | if (other == null) return 1; 858 | 859 | Tuple objTuple = other as Tuple; 860 | 861 | if (objTuple == null) { 862 | throw new ArgumentException(string.Format("Argument must be of type {0}.", this.GetType().ToString()), "other"); 863 | } 864 | 865 | int c = 0; 866 | 867 | c = comparer.Compare(m_Item1, objTuple.m_Item1); 868 | 869 | if (c != 0) return c; 870 | 871 | c = comparer.Compare(m_Item2, objTuple.m_Item2); 872 | 873 | if (c != 0) return c; 874 | 875 | c = comparer.Compare(m_Item3, objTuple.m_Item3); 876 | 877 | if (c != 0) return c; 878 | 879 | c = comparer.Compare(m_Item4, objTuple.m_Item4); 880 | 881 | if (c != 0) return c; 882 | 883 | c = comparer.Compare(m_Item5, objTuple.m_Item5); 884 | 885 | if (c != 0) return c; 886 | 887 | c = comparer.Compare(m_Item6, objTuple.m_Item6); 888 | 889 | if (c != 0) return c; 890 | 891 | c = comparer.Compare(m_Item7, objTuple.m_Item7); 892 | 893 | if (c != 0) return c; 894 | 895 | return comparer.Compare(m_Rest, objTuple.m_Rest); 896 | } 897 | 898 | public override int GetHashCode() { 899 | return ((IStructuralEquatable) this).GetHashCode(EqualityComparer.Default); 900 | } 901 | 902 | Int32 IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { 903 | // We want to have a limited hash in this case. We'll use the last 8 elements of the tuple 904 | ITuple t = (ITuple) m_Rest; 905 | if(t.Size >= 8) { return t.GetHashCode(comparer); } 906 | 907 | // In this case, the rest memeber has less than 8 elements so we need to combine some our elements with the elements in rest 908 | int k = 8 - t.Size; 909 | switch(k) { 910 | case 1: 911 | return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item7), t.GetHashCode(comparer)); 912 | case 2: 913 | return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item6), comparer.GetHashCode(m_Item7), t.GetHashCode(comparer)); 914 | case 3: 915 | return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item5), comparer.GetHashCode(m_Item6), comparer.GetHashCode(m_Item7), t.GetHashCode(comparer)); 916 | case 4: 917 | return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item4), comparer.GetHashCode(m_Item5), comparer.GetHashCode(m_Item6), comparer.GetHashCode(m_Item7), t.GetHashCode(comparer)); 918 | case 5: 919 | return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item3), comparer.GetHashCode(m_Item4), comparer.GetHashCode(m_Item5), comparer.GetHashCode(m_Item6), comparer.GetHashCode(m_Item7), t.GetHashCode(comparer)); 920 | case 6: 921 | return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item2), comparer.GetHashCode(m_Item3), comparer.GetHashCode(m_Item4), comparer.GetHashCode(m_Item5), comparer.GetHashCode(m_Item6), comparer.GetHashCode(m_Item7), t.GetHashCode(comparer)); 922 | case 7: 923 | return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item1), comparer.GetHashCode(m_Item2), comparer.GetHashCode(m_Item3), comparer.GetHashCode(m_Item4), comparer.GetHashCode(m_Item5), comparer.GetHashCode(m_Item6), comparer.GetHashCode(m_Item7), t.GetHashCode(comparer)); 924 | } 925 | // Contract.Assert(false, "Missed all cases for computing Tuple hash code"); 926 | Debug.Assert(false, "Missed all cases for computing Tuple hash code"); 927 | return -1; 928 | } 929 | 930 | Int32 ITuple.GetHashCode(IEqualityComparer comparer) { 931 | return ((IStructuralEquatable) this).GetHashCode(comparer); 932 | } 933 | public override string ToString() { 934 | StringBuilder sb = new StringBuilder(); 935 | sb.Append("("); 936 | return ((ITuple)this).ToString(sb); 937 | } 938 | 939 | string ITuple.ToString(StringBuilder sb) { 940 | sb.Append(m_Item1); 941 | sb.Append(", "); 942 | sb.Append(m_Item2); 943 | sb.Append(", "); 944 | sb.Append(m_Item3); 945 | sb.Append(", "); 946 | sb.Append(m_Item4); 947 | sb.Append(", "); 948 | sb.Append(m_Item5); 949 | sb.Append(", "); 950 | sb.Append(m_Item6); 951 | sb.Append(", "); 952 | sb.Append(m_Item7); 953 | sb.Append(", "); 954 | return ((ITuple)m_Rest).ToString(sb); 955 | } 956 | 957 | int ITuple.Size { 958 | get { 959 | return 7 + ((ITuple)m_Rest).Size; 960 | } 961 | } 962 | } 963 | } 964 | 965 | #endif 966 | -------------------------------------------------------------------------------- /core/UnityPackage/NetLegacySupport.unitypackage.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "NetLegacySupport", 3 | "version": "1.1.1", 4 | "authors": [ "Microsoft" ], 5 | "owners": [ "Esun Kim" ], 6 | "description": "Action, Func, Tuple and ConcurrentDictionary for Unity3D. This is a backport from .NET Core.", 7 | "files": [ 8 | "../Action.Net35/bin/Release/NetLegacySupport.Action.dll", 9 | "../ConcurrentDictionary.Net35/bin/Release/NetLegacySupport.ConcurrentDictionary.dll", 10 | "../Tuple.Net35/bin/Release/NetLegacySupport.Tuple.dll" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tools/nuget/NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /tools/nuget/NuGet.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildProjectDirectory)\..\ 5 | 6 | 7 | false 8 | 9 | 10 | false 11 | 12 | 13 | true 14 | 15 | 16 | false 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | 28 | 29 | 30 | $([System.IO.Path]::Combine($(SolutionDir), ".nuget")) 31 | 32 | 33 | 34 | 35 | $(SolutionDir).nuget 36 | 37 | 38 | 39 | $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName.Replace(' ', '_')).config 40 | $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName).config 41 | 42 | 43 | 44 | $(MSBuildProjectDirectory)\packages.config 45 | $(PackagesProjectConfig) 46 | 47 | 48 | 49 | 50 | $(NuGetToolsPath)\NuGet.exe 51 | @(PackageSource) 52 | 53 | "$(NuGetExePath)" 54 | mono --runtime=v4.0.30319 "$(NuGetExePath)" 55 | 56 | $(TargetDir.Trim('\\')) 57 | 58 | -RequireConsent 59 | -NonInteractive 60 | 61 | "$(SolutionDir) " 62 | "$(SolutionDir)" 63 | 64 | 65 | $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir) 66 | $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols 67 | 68 | 69 | 70 | RestorePackages; 71 | $(BuildDependsOn); 72 | 73 | 74 | 75 | 76 | $(BuildDependsOn); 77 | BuildPackage; 78 | 79 | 80 | 81 | 82 | 83 | 84 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 99 | 100 | 103 | 104 | 105 | 106 | 108 | 109 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 141 | 142 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /tools/nuget/nuget.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaladLab/NetLegacySupport/2678ef748bf21245ecb20394f92aaf236e7396e7/tools/nuget/nuget.exe -------------------------------------------------------------------------------- /tools/nuget/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | --------------------------------------------------------------------------------