@@ -49,7 +49,7 @@ public class CsvExport
49
49
/// <summary>
50
50
/// The current row
51
51
/// </summary>
52
- List < string > _currentRow { get { return _rows [ _rows . Count - 1 ] ; } }
52
+ List < string > _currentRow = null ;
53
53
54
54
/// <summary>
55
55
/// The string used to separate columns in the output
@@ -98,7 +98,10 @@ public CsvExport(string columnSeparator = ",", bool includeColumnSeparatorDefini
98
98
/// </summary>
99
99
public object this [ string field ]
100
100
{
101
- set {
101
+ set
102
+ {
103
+ if ( _currentRow is null ) return ; // no row has been added yet
104
+
102
105
// Keep track of the field names
103
106
if ( ! _fields . TryGetValue ( field , out int num ) ) //get the field's index
104
107
{
@@ -119,7 +122,8 @@ public object this[string field]
119
122
/// </summary>
120
123
public void AddRow ( )
121
124
{
122
- _rows . Add ( new ( _fields . Count ) ) ;
125
+ _currentRow = new ( _fields . Count ) ;
126
+ _rows . Add ( _currentRow ) ;
123
127
}
124
128
125
129
/// <summary>
@@ -129,7 +133,7 @@ public void AddRows<T>(IEnumerable<T> list)
129
133
{
130
134
if ( list . Any ( ) )
131
135
{
132
- var values = typeof ( T ) . GetProperties ( ) ;
136
+ var values = ReflectionCache < T > . Properties ;
133
137
foreach ( T obj in list )
134
138
{
135
139
AddRow ( ) ;
@@ -157,27 +161,24 @@ public static string MakeValueCsvFriendly(object value, string columnSeparator =
157
161
if ( value == null ) return "" ;
158
162
if ( value is INullable && ( ( INullable ) value ) . IsNull ) return "" ;
159
163
160
- string output ;
161
164
if ( value is DateTime date )
162
165
{
163
166
if ( date . TimeOfDay . TotalSeconds == 0 )
164
167
{
165
- output = date . ToString ( "yyyy-MM-dd" ) ;
168
+ return date . ToString ( "yyyy-MM-dd" ) ;
166
169
}
167
170
else
168
171
{
169
- output = date . ToString ( "yyyy-MM-dd HH:mm:ss" ) ;
172
+ return date . ToString ( "yyyy-MM-dd HH:mm:ss" ) ;
170
173
}
171
174
}
172
- else
173
- {
174
- output = value . ToString ( ) . Trim ( ) ;
175
- }
175
+
176
+ var output = value . ToString ( ) . Trim ( ) ;
176
177
177
178
if ( output . Length > 30000 ) //cropping value for stupid Excel
178
179
output = output . Substring ( 0 , 30000 ) ;
179
180
180
- if ( output . Contains ( columnSeparator ) || output . Contains ( " \" " ) || output . Contains ( " \n " ) || output . Contains ( " \r " ) )
181
+ if ( output . Contains ( columnSeparator ) || output . Contains ( ' \" ' ) || output . Contains ( ' \n ' ) || output . Contains ( ' \r ' ) )
181
182
output = '"' + output . Replace ( "\" " , "\" \" " ) + '"' ;
182
183
183
184
return output ;
@@ -277,4 +278,10 @@ public MemoryStream ExportAsMemoryStream(Encoding encoding = null)
277
278
return ms ;
278
279
}
279
280
}
281
+
282
+ internal static class ReflectionCache < T >
283
+ {
284
+ private static System . Reflection . PropertyInfo [ ] _properties ;
285
+ public static System . Reflection . PropertyInfo [ ] Properties => _properties ??= typeof ( T ) . GetProperties ( ) ;
286
+ }
280
287
}
0 commit comments