mirror of
https://github.com/radzenhq/radzen-blazor.git
synced 2026-07-08 18:16:08 +00:00
Six call sites that build a string once and either return or assign it now go through the thread-local cache instead of allocating a fresh StringBuilder on every call: - NumberFormat.FormatDate - NumberFormat.FormatNumber (outer builder; the inner thousand-grouping builder stays a direct allocation because it is nested inside the outer cached one) - NumberFormat.FormatScientific - CsvWriter.BuildContent - Worksheet.InvalidateFormulasReferencing (formula rebuild) - ColumnRef.ToString — additionally drops the stackalloc<char>; appends digits least-significant first then reverses in place via the StringBuilder indexer Sites left as direct 'new StringBuilder()': CsvReader.ParseCsv, NumberFormatParser.SplitSections / ParseSection, FormulaLexer ScanTrivia / ScanStringLiteral / ScanNumericLiteral. Each either holds two parallel builders, reuses one across many fields with Clear, or has multiple ToString() / return paths that would need try/finally release plumbing.
82 lines
2.7 KiB
C#
82 lines
2.7 KiB
C#
using System;
|
|
using System.Text;
|
|
|
|
namespace Radzen.Documents.Spreadsheet;
|
|
|
|
#nullable enable
|
|
|
|
/// <summary>
|
|
/// Represents a reference to a column in a spreadsheet.
|
|
/// </summary>
|
|
public readonly struct ColumnRef(int column) : IEquatable<ColumnRef>
|
|
{
|
|
/// <summary>
|
|
/// Returns the column index for the column reference.
|
|
/// The column index is zero-based, so the first column (A) corresponds to 0.
|
|
/// </summary>
|
|
public int Column { get; } = column;
|
|
|
|
/// <summary>
|
|
/// Checks if the column reference is equal to another column reference.
|
|
/// </summary>
|
|
public bool Equals(ColumnRef other) => Column == other.Column;
|
|
|
|
/// <summary>
|
|
/// Returns a string representation of the column reference in A1 notation.
|
|
/// For example, if the column reference is (0), it returns "A:A";
|
|
/// </summary>
|
|
public override string ToString()
|
|
{
|
|
var address = ToString(Column);
|
|
|
|
return $"{address}:{address}";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts a zero-based column index to its corresponding column letter(s) in A1 notation.
|
|
/// For example, 0 corresponds to "A", 1 to "B",
|
|
/// 26 to "AA", 27 to "AB", and so on.
|
|
/// </summary>
|
|
/// <param name="column">The zero-based column index.</param>
|
|
/// <returns>A string representing the column in A1 notation.</returns>
|
|
/// <exception cref="ArgumentOutOfRangeException">Thrown when the column index is negative.</exception>
|
|
public static string ToString(int column)
|
|
{
|
|
if (column < 0)
|
|
{
|
|
throw new ArgumentOutOfRangeException(nameof(column), "Column index must be non-negative.");
|
|
}
|
|
|
|
var sb = StringBuilderCache.Acquire();
|
|
var start = sb.Length;
|
|
column++;
|
|
while (column > 0)
|
|
{
|
|
column--;
|
|
sb.Append((char)('A' + column % 26));
|
|
column /= 26;
|
|
}
|
|
// Digits were appended least-significant first; reverse in place.
|
|
for (int i = start, j = sb.Length - 1; i < j; i++, j--)
|
|
{
|
|
(sb[i], sb[j]) = (sb[j], sb[i]);
|
|
}
|
|
return StringBuilderCache.GetStringAndRelease(sb);
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public override bool Equals(object? obj) => obj is ColumnRef address && Equals(address);
|
|
|
|
/// <inheritdoc/>
|
|
public override int GetHashCode() => Column.GetHashCode();
|
|
|
|
/// <summary>
|
|
/// Checks if the column reference is equal to another column reference.
|
|
/// </summary>
|
|
public static bool operator ==(ColumnRef left, ColumnRef right) => left.Equals(right);
|
|
|
|
/// <summary>
|
|
/// Checks if the column reference is not equal to another column reference.
|
|
/// </summary>
|
|
public static bool operator !=(ColumnRef left, ColumnRef right) => !left.Equals(right);
|
|
} |