diff --git a/.github/workflows/CD.yml b/.github/workflows/CD.yml
index fd58dfb0..54aa4c43 100644
--- a/.github/workflows/CD.yml
+++ b/.github/workflows/CD.yml
@@ -24,7 +24,7 @@ jobs:
- name: Setup .NET Core
uses: actions/setup-dotnet@v4
with:
- dotnet-version: '8.0.x'
+ dotnet-version: '9.0.x'
- name: Display dotnet version
run: dotnet --version
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 831ba07a..c2fe2483 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -16,7 +16,7 @@ jobs:
- name: Setup .NET Core
uses: actions/setup-dotnet@v4
with:
- dotnet-version: '8.0.x'
+ dotnet-version: '9.0.x'
- name: Display dotnet version
run: dotnet --version
diff --git a/CsvHelper.sln b/CsvHelper.sln
deleted file mode 100644
index 98749be6..00000000
--- a/CsvHelper.sln
+++ /dev/null
@@ -1,59 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 17
-VisualStudioVersion = 17.2.32210.308
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{6445B2A3-9E05-4ABF-AE2E-C875773B277A}"
- ProjectSection(SolutionItems) = preProject
- .editorconfig = .editorconfig
- .gitignore = .gitignore
- README.markdown = README.markdown
- EndProjectSection
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CsvHelper", "src\CsvHelper\CsvHelper.csproj", "{ECF9E2A8-3592-4DA4-9FAB-BFA56AD44B9C}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CsvHelper.Tests", "tests\CsvHelper.Tests\CsvHelper.Tests.csproj", "{6859ECD8-81AE-4E74-A926-5726AAD7EE81}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CsvHelper.Performance", "performance\CsvHelper.Performance\CsvHelper.Performance.csproj", "{F1C225F2-92FC-41BB-94BF-733454DD2A9D}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestApp", "TestApp\TestApp.csproj", "{8C33E5DF-2F2E-4FE3-91DD-C6683B310221}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {ECF9E2A8-3592-4DA4-9FAB-BFA56AD44B9C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {ECF9E2A8-3592-4DA4-9FAB-BFA56AD44B9C}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {ECF9E2A8-3592-4DA4-9FAB-BFA56AD44B9C}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {ECF9E2A8-3592-4DA4-9FAB-BFA56AD44B9C}.Release|Any CPU.Build.0 = Release|Any CPU
- {6859ECD8-81AE-4E74-A926-5726AAD7EE81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6859ECD8-81AE-4E74-A926-5726AAD7EE81}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6859ECD8-81AE-4E74-A926-5726AAD7EE81}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {6859ECD8-81AE-4E74-A926-5726AAD7EE81}.Release|Any CPU.Build.0 = Release|Any CPU
- {F1C225F2-92FC-41BB-94BF-733454DD2A9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {F1C225F2-92FC-41BB-94BF-733454DD2A9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {F1C225F2-92FC-41BB-94BF-733454DD2A9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {F1C225F2-92FC-41BB-94BF-733454DD2A9D}.Release|Any CPU.Build.0 = Release|Any CPU
- {8C33E5DF-2F2E-4FE3-91DD-C6683B310221}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {8C33E5DF-2F2E-4FE3-91DD-C6683B310221}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {8C33E5DF-2F2E-4FE3-91DD-C6683B310221}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {8C33E5DF-2F2E-4FE3-91DD-C6683B310221}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {7F48D3EE-214D-45F4-AC6A-3E95C3A25E9F}
- EndGlobalSection
- GlobalSection(Performance) = preSolution
- HasPerformanceSessions = true
- EndGlobalSection
- GlobalSection(Performance) = preSolution
- HasPerformanceSessions = true
- EndGlobalSection
- GlobalSection(Performance) = preSolution
- HasPerformanceSessions = true
- EndGlobalSection
-EndGlobal
diff --git a/CsvHelper.slnx b/CsvHelper.slnx
new file mode 100644
index 00000000..c9115162
--- /dev/null
+++ b/CsvHelper.slnx
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TestApp/TestApp.csproj b/TestApp/TestApp.csproj
index c1d8fad4..81170744 100644
--- a/TestApp/TestApp.csproj
+++ b/TestApp/TestApp.csproj
@@ -2,7 +2,7 @@
Exe
- net8.0
+ net9.0
enable
enable
true
diff --git a/performance/CsvHelper.Performance/CsvHelper.Performance.csproj b/performance/CsvHelper.Performance/CsvHelper.Performance.csproj
index 2944d35c..92fcef3d 100644
--- a/performance/CsvHelper.Performance/CsvHelper.Performance.csproj
+++ b/performance/CsvHelper.Performance/CsvHelper.Performance.csproj
@@ -2,12 +2,12 @@
Exe
- net8.0
+ net9.0
enable
-
+
diff --git a/src/CsvHelper/Configuration/ConfigurationFunctions.cs b/src/CsvHelper/Configuration/ConfigurationFunctions.cs
index eb6c9c1b..c17102c3 100644
--- a/src/CsvHelper/Configuration/ConfigurationFunctions.cs
+++ b/src/CsvHelper/Configuration/ConfigurationFunctions.cs
@@ -8,8 +8,6 @@ namespace CsvHelper.Configuration;
/// Holds the default callback methods for delegate members of CsvHelper.Configuration.Configuration.
public static class ConfigurationFunctions
{
- private static readonly char[] lineEndingChars = ['\r', '\n'];
-
///
/// Throws a MissingFieldException.
///
diff --git a/src/CsvHelper/Configuration/CsvConfiguration.cs b/src/CsvHelper/Configuration/CsvConfiguration.cs
index 092e48e9..1b4c7ede 100644
--- a/src/CsvHelper/Configuration/CsvConfiguration.cs
+++ b/src/CsvHelper/Configuration/CsvConfiguration.cs
@@ -47,9 +47,6 @@ public record CsvConfiguration : IReaderConfiguration, IWriterConfiguration
///
public virtual bool DetectColumnCountChanges { get; set; }
- ///
- public virtual IComparer DynamicPropertySort { get; set; }
-
///
public virtual Encoding Encoding { get; set; } = Encoding.UTF8;
@@ -65,18 +62,6 @@ public record CsvConfiguration : IReaderConfiguration, IWriterConfiguration
///
public virtual bool IgnoreBlankLines { get; set; } = true;
- ///
- public virtual bool IgnoreReferences { get; set; }
-
- ///
- public virtual bool IncludePrivateMembers { get; set; }
-
- ///
- public virtual char[] InjectionCharacters { get; set; } = ['=', '@', '+', '-'];
-
- ///
- public virtual char InjectionEscapeCharacter { get; set; } = '\t';
-
///
public bool IsNewLineSet { get; private set; }
@@ -122,10 +107,7 @@ public virtual string NewLine
public virtual TrimOptions TrimOptions { get; set; }
///
- public virtual bool UseNewObjectForNullReferenceMembers { get; set; } = true;
-
- ///
- public virtual char[] WhiteSpaceChars { get; set; } = new char[] { ' ' };
+ public virtual char[] WhiteSpaceChars { get; set; } = [' '];
///
/// Initializes a new instance of the class
diff --git a/src/CsvHelper/Configuration/IReaderConfiguration.cs b/src/CsvHelper/Configuration/IReaderConfiguration.cs
index 7165cb17..c183d991 100644
--- a/src/CsvHelper/Configuration/IReaderConfiguration.cs
+++ b/src/CsvHelper/Configuration/IReaderConfiguration.cs
@@ -52,13 +52,6 @@ public interface IReaderConfiguration : IParserConfiguration
///
ShouldSkipRecord ShouldSkipRecord { get; }
- ///
- /// Gets a value indicating if private
- /// member should be read from and written to.
- /// true to include private member, otherwise false. Default is false.
- ///
- bool IncludePrivateMembers { get; }
-
///
/// Gets a value indicating whether changes in the column
/// count should be detected. If true, a
diff --git a/src/CsvHelper/CsvHelper.csproj b/src/CsvHelper/CsvHelper.csproj
index 431507d4..9107b88e 100644
--- a/src/CsvHelper/CsvHelper.csproj
+++ b/src/CsvHelper/CsvHelper.csproj
@@ -8,7 +8,7 @@
CsvHelper
- net8.0
+ net9.0
CsvHelper
en-US
true
@@ -46,7 +46,7 @@
-
+
\ No newline at end of file
diff --git a/src/CsvHelper/CsvReader.cs b/src/CsvHelper/CsvReader.cs
index c3edf90d..71a25074 100644
--- a/src/CsvHelper/CsvReader.cs
+++ b/src/CsvHelper/CsvReader.cs
@@ -19,10 +19,8 @@ public class CsvReader : IReader
private readonly bool hasHeaderRecord;
private readonly ShouldSkipRecord shouldSkipRecord;
private readonly ReadingExceptionOccurred readingExceptionOccurred;
- private readonly CultureInfo cultureInfo;
private readonly bool ignoreBlankLines;
private readonly MissingFieldFound missingFieldFound;
- private readonly bool includePrivateMembers;
private readonly PrepareHeaderForMatch prepareHeaderForMatch;
private CsvContext context;
@@ -79,11 +77,9 @@ public CsvReader(IParser parser)
context = parser.Context ?? throw new InvalidOperationException($"For {nameof(IParser)} to be used in {nameof(CsvReader)}, {nameof(IParser.Context)} must also implement {nameof(CsvContext)}.");
context.Reader = this;
- cultureInfo = Configuration.CultureInfo;
detectColumnCountChanges = Configuration.DetectColumnCountChanges;
hasHeaderRecord = Configuration.HasHeaderRecord;
ignoreBlankLines = Configuration.IgnoreBlankLines;
- includePrivateMembers = Configuration.IncludePrivateMembers;
missingFieldFound = Configuration.MissingFieldFound;
prepareHeaderForMatch = Configuration.PrepareHeaderForMatch;
readingExceptionOccurred = Configuration.ReadingExceptionOccurred;
@@ -261,16 +257,13 @@ public virtual string GetField(string name, int index)
///
public virtual int GetFieldIndex(string name, int index = 0, bool isTryGet = false)
{
- return GetFieldIndex(new[] { name }, index, isTryGet);
+ return GetFieldIndex([name], index, isTryGet);
}
///
public virtual int GetFieldIndex(string[] names, int index = 0, bool isTryGet = false, bool isOptional = false)
{
- if (names == null)
- {
- throw new ArgumentNullException(nameof(names));
- }
+ ArgumentNullException.ThrowIfNull(names);
if (!hasHeaderRecord)
{
@@ -284,9 +277,9 @@ public virtual int GetFieldIndex(string[] names, int index = 0, bool isTryGet =
// Caching the named index speeds up mappings that use ConvertUsing tremendously.
var nameKey = string.Join("_", names) + index;
- if (namedIndexCache.ContainsKey(nameKey))
+ if (namedIndexCache.TryGetValue(nameKey, out (string, int) value))
{
- (var cachedName, var cachedIndex) = namedIndexCache[nameKey];
+ (var cachedName, var cachedIndex) = value;
return namedIndexes[cachedName][cachedIndex];
}
@@ -376,13 +369,13 @@ protected virtual void ParseNamedIndexes()
{
var args = new PrepareHeaderForMatchArgs(headerRecord[i], i);
var name = prepareHeaderForMatch(args);
- if (namedIndexes.ContainsKey(name))
+ if (namedIndexes.TryGetValue(name, out List value))
{
- namedIndexes[name].Add(i);
+ value.Add(i);
}
else
{
- namedIndexes[name] = new List { i };
+ namedIndexes[name] = [i];
}
}
}
diff --git a/src/CsvHelper/CsvWriter.cs b/src/CsvHelper/CsvWriter.cs
index 141c4703..8a7ff9ca 100644
--- a/src/CsvHelper/CsvWriter.cs
+++ b/src/CsvHelper/CsvWriter.cs
@@ -10,15 +10,12 @@ namespace CsvHelper;
public class CsvWriter : IDisposable
{
private readonly TextWriter writer;
- private string newLine = "\r\n";
- private string quoteString = "\"";
- private string delimiter = ";";
- private readonly bool leaveOpen;
- private char quote = '"';
+ private readonly string newLine = "\r\n";
+ private readonly string quoteString = "\"";
+ private readonly string delimiter = ";";
+ private readonly char quote = '"';
private readonly char comment = '#';
private readonly string escapeQuoteString;
- private readonly char[] injectionCharacters;
- private readonly char injectionEscapeCharacter;
private int row = 1;
private int index;
@@ -47,7 +44,7 @@ public class CsvWriter : IDisposable
public CsvWriter(TextWriter writer)
{
this.writer = writer;
- escapeQuoteString = new string(new[] { '"' });
+ escapeQuoteString = new string(['"']);
buffer = new char[bufferSize];
}
@@ -82,7 +79,7 @@ public virtual void WriteHeader(string[] headers)
headerRecord.Add(header);
}
- HeaderRecord = headerRecord.ToArray();
+ HeaderRecord = [.. headerRecord];
}
///
@@ -139,7 +136,7 @@ private bool ShouldQuote(string field)
(
field.Contains(quote) // Contains quote
|| field[0] == ' ' // Starts with a space
- || field[field.Length - 1] == ' ' // Ends with a space
+ || field[^1] == ' ' // Ends with a space
|| (delimiter.Length > 0 && field.Contains(delimiter)) // Contains delimiter
|| field.Contains(newLine) // Contains newline
);
@@ -147,28 +144,6 @@ private bool ShouldQuote(string field)
return shouldQuote;
}
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- protected virtual string SanitizeForInjection(string field)
- {
- if (string.IsNullOrEmpty(field))
- {
- return field;
- }
-
- if (ArrayHelper.Contains(injectionCharacters, field[0]))
- {
- return injectionEscapeCharacter + field;
- }
-
- if (field[0] == quote && ArrayHelper.Contains(injectionCharacters, field[1]))
- {
- return field[0].ToString() + injectionEscapeCharacter.ToString() + field.Substring(1);
- }
-
- return field;
- }
-
///
public virtual void NextRecord()
{
@@ -266,11 +241,7 @@ protected virtual void Dispose(bool disposing)
if (disposing)
{
// Dispose managed state (managed objects)
-
- if (!leaveOpen)
- {
- writer.Dispose();
- }
+ writer.Dispose();
}
// Free unmanaged resources (unmanaged objects) and override finalizer
@@ -301,11 +272,7 @@ protected virtual async ValueTask DisposeAsync(bool disposing)
if (disposing)
{
// Dispose managed state (managed objects)
-
- if (!leaveOpen)
- {
- await writer.DisposeAsync().ConfigureAwait(false);
- }
+ await writer.DisposeAsync().ConfigureAwait(false);
}
// Free unmanaged resources (unmanaged objects) and override finalizer
diff --git a/src/CsvHelper/packages.lock.json b/src/CsvHelper/packages.lock.json
index 6b85a9b1..48329d1f 100644
--- a/src/CsvHelper/packages.lock.json
+++ b/src/CsvHelper/packages.lock.json
@@ -1,12 +1,12 @@
{
"version": 1,
"dependencies": {
- "net8.0": {
+ "net9.0": {
"Microsoft.NET.ILLink.Tasks": {
"type": "Direct",
- "requested": "[8.0.4, )",
- "resolved": "8.0.4",
- "contentHash": "PZb5nfQ+U19nhnmnR9T1jw+LTmozhuG2eeuzuW5A7DqxD/UXW2ucjmNJqnqOuh8rdPzM3MQXoF8AfFCedJdCUw=="
+ "requested": "[9.0.10, )",
+ "resolved": "9.0.10",
+ "contentHash": "sseaSJcBxKEpkc59hnB00b3NmJdGvJLfj74HK+nucHxERxbZSUREuWKjC9ywc+HdzJvJyiP2eiyEOROaGSfcPw=="
},
"Microsoft.SourceLink.GitHub": {
"type": "Direct",
@@ -20,9 +20,9 @@
},
"Nerdbank.GitVersioning": {
"type": "Direct",
- "requested": "[3.6.133, )",
- "resolved": "3.6.133",
- "contentHash": "VZWMd5YAeDxpjWjAP/X6bAxnRMiEf6tES/ITN0X5CHJgkWLLeHGmEALivmTAfYM6P+P/3Szy6VCITUAkqjcHVw=="
+ "requested": "[3.8.118, )",
+ "resolved": "3.8.118",
+ "contentHash": "cRaG+ICcECG+CzbtQyUV2WftH7yl2B02AjYGGNScXx8TwYavZYwhCewBTiC0qTcsac7m6AzBUYna5xzBWmTGYw=="
},
"Microsoft.Build.Tasks.Git": {
"type": "Transitive",
diff --git a/tests/CsvHelper.Tests/CsvHelper.Tests.csproj b/tests/CsvHelper.Tests/CsvHelper.Tests.csproj
index 71258014..37691459 100644
--- a/tests/CsvHelper.Tests/CsvHelper.Tests.csproj
+++ b/tests/CsvHelper.Tests/CsvHelper.Tests.csproj
@@ -1,7 +1,7 @@
- net8.0
+ net9.0
enable
@@ -11,16 +11,16 @@
-
-
+
+
-
-
-
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
diff --git a/tests/CsvHelper.Tests/CsvReaderTests.cs b/tests/CsvHelper.Tests/CsvReaderTests.cs
index 87c67882..4bf032a7 100644
--- a/tests/CsvHelper.Tests/CsvReaderTests.cs
+++ b/tests/CsvHelper.Tests/CsvReaderTests.cs
@@ -243,11 +243,6 @@ private struct TestStruct
public string Name { get; set; }
}
- private class OnlyFields
- {
- public string Name;
- }
-
private class TestBoolean
{
public bool BoolColumn { get; set; }