Skip to content

Commit c763c19

Browse files
committed
BREAKING: use separator char (not string)
1 parent c43b849 commit c763c19

2 files changed

Lines changed: 11 additions & 21 deletions

File tree

CsvExport/CsvExport.cs

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,7 @@ public class CsvExport
5252
List<object> _currentRow = null;
5353

5454
/// <summary>
55-
/// The string used to separate columns in the output
56-
/// </summary>
57-
private readonly string _columnSeparator;
58-
59-
/// <summary>
60-
/// When the separator is a single character, cached here for fast-path checks.
61-
/// <c>'\0'</c> means the separator is multi-char (use the string path).
55+
/// The character used to separate columns in the output
6256
/// </summary>
6357
private readonly char _separatorChar;
6458

@@ -92,10 +86,9 @@ public class CsvExport
9286
/// <param name="includeHeaderRow">
9387
/// Whether to include the header row with the columns names in the export
9488
/// </param>
95-
public CsvExport(string columnSeparator = ",", bool includeColumnSeparatorDefinitionPreamble = true, bool includeHeaderRow = true)
89+
public CsvExport(char columnSeparator = ',', bool includeColumnSeparatorDefinitionPreamble = true, bool includeHeaderRow = true)
9690
{
97-
_columnSeparator = columnSeparator;
98-
_separatorChar = columnSeparator.Length == 1 ? columnSeparator[0] : '\0';
91+
_separatorChar = columnSeparator;
9992
_includeColumnSeparatorDefinitionPreamble = includeColumnSeparatorDefinitionPreamble;
10093
_includeHeaderRow = includeHeaderRow;
10194
}
@@ -163,7 +156,7 @@ public void AddRows<T>(IEnumerable<T> list)
163156
/// The string used to separate columns in the output.
164157
/// By default this is a comma so that the generated output is a CSV document.
165158
/// </param>
166-
public static string MakeValueCsvFriendly(object value, string columnSeparator = ",")
159+
public static string MakeValueCsvFriendly(object value, char columnSeparator = ',')
167160
{
168161
var sb = new StringBuilder();
169162
new CsvExport(columnSeparator).WriteCsvFriendlyValues([value], new StringBuilderCsvWriter(sb));
@@ -211,8 +204,7 @@ private void WriteCsvFriendlyValues(IEnumerable<object> line, ICsvWriter writer)
211204
{
212205
if (!first)
213206
{
214-
if (_separatorChar != '\0') writer.Write(_separatorChar);
215-
else writer.Write(_columnSeparator);
207+
writer.Write(_separatorChar);
216208
}
217209
first = false;
218210

@@ -234,9 +226,7 @@ private void WriteCsvFriendlyValues(IEnumerable<object> line, ICsvWriter writer)
234226
output = output.Substring(0, 30000);
235227

236228
//fast path: single-char separator uses Contains(char) (ordinal, no culture table lookup)
237-
bool containsSeparator = _separatorChar != '\0'
238-
? output.Contains(_separatorChar)
239-
: output.Contains(_columnSeparator);
229+
bool containsSeparator = output.Contains(_separatorChar);
240230

241231
if (containsSeparator || output.Contains('\"') || output.Contains('\n') || output.Contains('\r'))
242232
{
@@ -277,7 +267,7 @@ public string Export()
277267
ICsvWriter writer = new StringBuilderCsvWriter(sb);
278268

279269
if (_includeColumnSeparatorDefinitionPreamble)
280-
sb.Append($"sep={_columnSeparator}\r\n");
270+
sb.Append($"sep={_separatorChar}\r\n");
281271

282272
foreach (var line in ExportToLines())
283273
{
@@ -330,7 +320,7 @@ public void WriteToStream(Stream stream, Encoding encoding = null)
330320

331321
if (_includeColumnSeparatorDefinitionPreamble)
332322
{
333-
sw.Write("sep="); sw.Write(_columnSeparator); sw.Write("\r\n"); //just tiny way to avoid string concatenation
323+
sw.Write("sep="); sw.Write(_separatorChar); sw.Write("\r\n"); //just tiny way to avoid string concatenation
334324
}
335325

336326
foreach (var line in ExportToLines())

UnitTests/UnitTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ public void WriteToFile()
118118
public void TestConstructorParameters()
119119
{
120120
// Test custom separator
121-
var export1 = new CsvExport(";");
121+
var export1 = new CsvExport(';');
122122
export1.AddRow();
123123
export1["Name"] = "John";
124124
export1["Value"] = "Test;Data";
@@ -128,15 +128,15 @@ public void TestConstructorParameters()
128128
Assert.IsTrue(result1.Contains("\"Test;Data\""));
129129

130130
// Test no preamble
131-
var export2 = new CsvExport(",", false);
131+
var export2 = new CsvExport(',', false);
132132
export2.AddRow();
133133
export2["Name"] = "John";
134134
string result2 = export2.Export();
135135
Assert.IsFalse(result2.Contains("sep="));
136136
Assert.IsTrue(result2.StartsWith("Name\r\n"));
137137

138138
// Test no header
139-
var export3 = new CsvExport(",", true, false);
139+
var export3 = new CsvExport(',', true, false);
140140
export3.AddRow();
141141
export3["Name"] = "John";
142142
string result3 = export3.Export();

0 commit comments

Comments
 (0)