diff --git a/.history/src/CsvHelper/CsvWriter_20251215023120.cs b/.history/src/CsvHelper/CsvWriter_20251215023120.cs
new file mode 100644
index 000000000..a7e4d9585
--- /dev/null
+++ b/.history/src/CsvHelper/CsvWriter_20251215023120.cs
@@ -0,0 +1,943 @@
+// Copyright 2009-2024 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Expressions;
+using CsvHelper.TypeConversion;
+using System.Collections;
+using System.Dynamic;
+using System.Globalization;
+using System.Linq.Expressions;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+#pragma warning disable 649
+#pragma warning disable 169
+
+namespace CsvHelper;
+
+///
+/// Used to write CSV files.
+///
+public class CsvWriter : IWriter
+{
+ private readonly TextWriter writer;
+ private readonly CsvContext context;
+ private readonly Lazy recordManager;
+ private readonly TypeConverterCache typeConverterCache;
+ private readonly TrimOptions trimOptions;
+ private readonly ShouldQuote shouldQuote;
+ private readonly MemberMapData reusableMemberMapData = new MemberMapData(null);
+ private readonly Dictionary typeConverterOptionsCache = new Dictionary();
+ private readonly string quoteString;
+ private readonly char quote;
+ private readonly CultureInfo cultureInfo;
+ private readonly char comment;
+ private readonly bool hasHeaderRecord;
+ private readonly bool includePrivateMembers;
+ private readonly IComparer? dynamicPropertySort;
+ private readonly string delimiter;
+ private readonly bool leaveOpen;
+ private readonly string newLine;
+ private readonly char[] injectionCharacters;
+ private readonly char injectionEscapeCharacter;
+ private readonly InjectionOptions injectionOptions;
+ private readonly CsvMode mode;
+ private readonly string escapeString;
+ private readonly string escapeQuoteString;
+ private readonly string escapeDelimiterString;
+ private readonly string escapeNewlineString;
+ private readonly string escapeEscapeString;
+
+ private bool disposed;
+ private bool hasHeaderBeenWritten;
+ private int row = 1;
+ private int index;
+ private char[] buffer;
+ private int bufferSize;
+ private int bufferPosition;
+ private Type? fieldType;
+
+ ///
+ public virtual string?[]? HeaderRecord { get; private set; }
+
+ ///
+ public virtual int Row => row;
+
+ ///
+ public virtual int Index => index;
+
+ ///
+ public virtual CsvContext Context => context;
+
+ ///
+ public virtual IWriterConfiguration Configuration { get; private set; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The writer.
+ /// The culture.
+ /// true to leave the open after the object is disposed, otherwise false.
+ public CsvWriter(TextWriter writer, CultureInfo culture, bool leaveOpen = false) : this(writer, new CsvConfiguration(culture), leaveOpen) { }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The writer.
+ /// The configuration.
+ /// true to leave the open after the object is disposed, otherwise false.
+ public CsvWriter(TextWriter writer, IWriterConfiguration configuration, bool leaveOpen = false)
+ {
+ configuration.Validate();
+
+ this.writer = writer;
+ Configuration = configuration;
+ context = new CsvContext(this);
+ typeConverterCache = context.TypeConverterCache;
+ recordManager = new Lazy(() => ObjectResolver.Current.Resolve(this));
+
+ comment = configuration.Comment;
+ bufferSize = configuration.BufferSize;
+ delimiter = configuration.Delimiter;
+ cultureInfo = configuration.CultureInfo;
+ dynamicPropertySort = configuration.DynamicPropertySort;
+ escapeDelimiterString = new string(configuration.Delimiter.SelectMany(c => new[] { configuration.Escape, c }).ToArray());
+ escapeNewlineString = new string(configuration.NewLine.SelectMany(c => new[] { configuration.Escape, c }).ToArray());
+ escapeQuoteString = new string(new[] { configuration.Escape, configuration.Quote });
+ escapeEscapeString = new string(new[] { configuration.Escape, configuration.Escape });
+ hasHeaderRecord = configuration.HasHeaderRecord;
+ includePrivateMembers = configuration.IncludePrivateMembers;
+ injectionCharacters = configuration.InjectionCharacters;
+ injectionEscapeCharacter = configuration.InjectionEscapeCharacter;
+ this.leaveOpen = leaveOpen;
+ mode = configuration.Mode;
+ newLine = configuration.NewLine;
+ quote = configuration.Quote;
+ quoteString = configuration.Quote.ToString();
+ escapeString = configuration.Escape.ToString();
+ injectionOptions = configuration.InjectionOptions;
+ shouldQuote = configuration.ShouldQuote;
+ trimOptions = configuration.TrimOptions;
+
+ buffer = new char[bufferSize];
+ }
+
+ ///
+ public virtual void WriteConvertedField(string? field, Type fieldType)
+ {
+ this.fieldType = fieldType;
+
+ if (field == null)
+ {
+ return;
+ }
+
+ WriteField(field);
+ }
+
+ ///
+ public virtual void WriteField(string? field)
+ {
+ if (field != null && (trimOptions & TrimOptions.Trim) == TrimOptions.Trim)
+ {
+ field = field.Trim();
+ }
+
+ fieldType ??= typeof(string);
+
+ var args = new ShouldQuoteArgs(field, fieldType, this);
+ var shouldQuoteResult = shouldQuote(args);
+
+ WriteField(field, shouldQuoteResult);
+ }
+
+ ///
+ public virtual void WriteField(string? field, bool shouldQuote)
+ {
+ if (mode == CsvMode.RFC4180)
+ {
+ // All quotes must be escaped.
+ if (shouldQuote)
+ {
+ if (escapeString != quoteString)
+ {
+ field = field?.Replace(escapeString, escapeEscapeString);
+ }
+
+ field = field?.Replace(quoteString, escapeQuoteString);
+ field = quote + field + quote;
+ }
+ }
+ else if (mode == CsvMode.Escape)
+ {
+ field = field?
+ .Replace(escapeString, escapeEscapeString)
+ .Replace(quoteString, escapeQuoteString)
+ .Replace(delimiter, escapeDelimiterString)
+ .Replace(newLine, escapeNewlineString);
+ }
+
+ if (injectionOptions != InjectionOptions.None)
+ {
+ field = SanitizeForInjection(field);
+ }
+
+ if (index > 0)
+ {
+ WriteToBuffer(delimiter);
+ }
+
+ WriteToBuffer(field);
+ index++;
+ fieldType = null;
+ }
+
+ ///
+ public virtual void WriteField(T? field)
+ {
+ var type = field == null ? typeof(string) : field.GetType();
+ var converter = typeConverterCache.GetConverter(type);
+ WriteField(field, converter);
+ }
+
+ ///
+ public virtual void WriteField(T? field, ITypeConverter converter)
+ {
+ var type = field == null ? typeof(string) : field.GetType();
+ reusableMemberMapData.TypeConverter = converter;
+ if (!typeConverterOptionsCache.TryGetValue(type, out TypeConverterOptions? typeConverterOptions))
+ {
+ typeConverterOptions = TypeConverterOptions.Merge(new TypeConverterOptions { CultureInfo = cultureInfo }, context.TypeConverterOptionsCache.GetOptions(type));
+ typeConverterOptionsCache.Add(type, typeConverterOptions);
+ }
+
+ reusableMemberMapData.TypeConverterOptions = typeConverterOptions;
+
+ var fieldString = converter.ConvertToString(field, this, reusableMemberMapData);
+
+ WriteConvertedField(fieldString, type);
+ }
+
+ ///
+ public virtual void WriteField(T? field)
+ {
+ var converter = typeConverterCache.GetConverter();
+
+ WriteField(field, converter);
+ }
+
+ ///
+ public virtual void WriteComment(string? text)
+ {
+ WriteField(comment + text, false);
+ }
+
+ ///
+ public virtual void WriteHeader()
+ {
+ WriteHeader(typeof(T));
+ }
+
+ ///
+ public virtual void WriteHeader(Type type)
+ {
+ if (type == null)
+ {
+ throw new ArgumentNullException(nameof(type));
+ }
+
+ if (type == typeof(object))
+ {
+ return;
+ }
+
+ if (context.Maps[type] == null)
+ {
+ context.Maps.Add(context.AutoMap(type));
+ }
+
+ var members = new MemberMapCollection();
+ members.AddMembers(context.Maps[type]!); // The map is added above.
+
+ var headerRecord = new List();
+
+ foreach (var member in members)
+ {
+ if (CanWrite(member))
+ {
+ if (member.Data.IndexEnd >= member.Data.Index)
+ {
+ var count = member.Data.IndexEnd - member.Data.Index + 1;
+ for (var i = 1; i <= count; i++)
+ {
+ var header = member.Data.Names.FirstOrDefault() + i;
+ WriteField(header);
+ headerRecord.Add(header);
+ }
+ }
+ else
+ {
+ var header = member.Data.Names.FirstOrDefault();
+ WriteField(header);
+ headerRecord.Add(header);
+ }
+ }
+ }
+
+ HeaderRecord = headerRecord.ToArray();
+
+ hasHeaderBeenWritten = true;
+ }
+
+ ///
+ /// Writes a dynamic header record.
+ ///
+ /// The header record to write.
+ /// Thrown when no record is passed.
+ public virtual void WriteDynamicHeader(IDynamicMetaObjectProvider? record)
+ {
+ if (record == null)
+ {
+ throw new ArgumentNullException(nameof(record));
+ }
+
+ var metaObject = record.GetMetaObject(Expression.Constant(record));
+ var names = metaObject.GetDynamicMemberNames().ToList();
+ if (dynamicPropertySort != null)
+ {
+ names = names.OrderBy(name => name, dynamicPropertySort).ToList();
+ }
+
+ HeaderRecord = names.ToArray();
+
+ foreach (var name in names)
+ {
+ WriteField(name);
+ }
+
+ hasHeaderBeenWritten = true;
+ }
+
+ ///
+ public virtual void WriteRecord(T? record)
+ {
+ try
+ {
+ var recordTypeInfo = GetTypeInfoForRecord(record);
+ var write = recordManager.Value.GetWriteDelegate(recordTypeInfo);
+ write(record);
+ }
+ catch (TargetInvocationException ex)
+ {
+ if (ex.InnerException != null)
+ {
+ throw ex.InnerException;
+ }
+ else
+ {
+ throw;
+ }
+ }
+ catch (Exception ex) when (ex is not CsvHelperException)
+ {
+ throw new WriterException(context, "An unexpected error occurred. See inner exception for details.", ex);
+ }
+ }
+
+ ///
+ public virtual void WriteRecords(IEnumerable records)
+ {
+ // Changes in this method require changes in method WriteRecords(IEnumerable records) also.
+
+ var enumerator = records.GetEnumerator();
+
+ try
+ {
+ if (!enumerator.MoveNext())
+ {
+ return;
+ }
+
+ if (WriteHeaderFromRecord(enumerator.Current))
+ {
+ NextRecord();
+ }
+
+ Action