@@ -358,68 +358,94 @@ internal static string ItemsToCsv(IEnumerable items, CSVSettings settings, char[
358358
359359 // Special cases for other types of serialization
360360 string s ;
361- var itemType = item . GetType ( ) ;
362- var interfaces = itemType . GetInterfaces ( ) ;
363- bool isEnumerable = false ;
364- if ( itemType != typeof ( string ) )
361+ if ( item is string )
365362 {
366- foreach ( var itemInterface in interfaces )
367- {
368- if ( itemInterface == typeof ( IEnumerable ) )
369- {
370- isEnumerable = true ;
371- }
372- }
373- }
374-
375- if ( item is DateTime )
363+ s = item as string ;
364+ }
365+ else if ( item is DateTime )
376366 {
377367 s = ( ( DateTime ) item ) . ToString ( settings . DateTimeFormat ) ;
378368 }
379- else if ( isEnumerable )
369+ else
380370 {
381- IEnumerable enumerable = item as IEnumerable ;
382- s = string . Empty ;
383- switch ( settings . NestedArrayBehavior )
371+ var itemType = item . GetType ( ) ;
372+ var interfaces = itemType . GetInterfaces ( ) ;
373+ bool isEnumerable = false ;
374+ if ( itemType != typeof ( string ) )
384375 {
385- case ArrayOptions . ToString :
386- s = item . ToString ( ) ;
387- break ;
388- case ArrayOptions . CountItems :
389- // from https://stackoverflow.com/questions/3546051/how-to-invoke-system-linq-enumerable-count-on-ienumerablet-using-reflection
390- if ( enumerable != null )
376+ foreach ( var itemInterface in interfaces )
377+ {
378+ if ( itemInterface == typeof ( IEnumerable ) )
391379 {
392- int enumerableCount = 0 ;
393- var iter = enumerable . GetEnumerator ( ) ;
394- using ( iter as IDisposable )
380+ isEnumerable = true ;
381+ }
382+ }
383+ }
384+
385+ // Treat enumerables as a simple class of objects that can be unrolled
386+ if ( isEnumerable )
387+ {
388+ IEnumerable enumerable = item as IEnumerable ;
389+ s = string . Empty ;
390+ switch ( settings . NestedArrayBehavior )
391+ {
392+ case ArrayOptions . ToString :
393+ s = item . ToString ( ) ;
394+ break ;
395+ case ArrayOptions . CountItems :
396+ if ( enumerable != null )
395397 {
396- while ( iter . MoveNext ( ) )
398+ int enumerableCount = 0 ;
399+ var iter = enumerable . GetEnumerator ( ) ;
400+ using ( iter as IDisposable )
397401 {
398- enumerableCount ++ ;
402+ while ( iter . MoveNext ( ) )
403+ {
404+ enumerableCount ++ ;
405+ }
399406 }
407+ s = enumerableCount . ToString ( ) ;
400408 }
401-
402- s = enumerableCount . ToString ( ) ;
403- }
404-
405- break ;
406- case ArrayOptions . TreatAsNull :
407- if ( settings . AllowNull )
408- {
409- s = settings . NullToken ;
410- }
411- break ;
412- case ArrayOptions . RecursiveSerialization :
413- if ( enumerable != null )
414- {
415- s = ItemsToCsv ( enumerable , settings , riskyChars , forceQualifierTypes ) ;
416- }
417- break ;
409+ break ;
410+ case ArrayOptions . TreatAsNull :
411+ if ( settings . AllowNull )
412+ {
413+ s = settings . NullToken ;
414+ }
415+ else
416+ {
417+ s = string . Empty ;
418+ }
419+ break ;
420+ case ArrayOptions . RecursiveSerialization :
421+ if ( enumerable != null )
422+ {
423+ s = ItemsToCsv ( enumerable , settings , riskyChars , forceQualifierTypes ) ;
424+ }
425+ else
426+ {
427+ s = string . Empty ;
428+ }
429+ break ;
430+ }
431+ }
432+ else if ( itemType . IsClass && settings . NestedObjectBehavior == ObjectOptions . RecursiveSerialization )
433+ {
434+ var nestedItems = new List < object > ( ) ;
435+ foreach ( var field in itemType . GetFields ( ) )
436+ {
437+ nestedItems . Add ( field . GetValue ( item ) ) ;
438+ }
439+ foreach ( var prop in itemType . GetProperties ( ) )
440+ {
441+ nestedItems . Add ( prop . GetValue ( item , null ) ) ;
442+ }
443+ s = ItemsToCsv ( nestedItems , settings , riskyChars , forceQualifierTypes ) ;
444+ }
445+ else
446+ {
447+ s = item . ToString ( ) ;
418448 }
419- }
420- else
421- {
422- s = item . ToString ( ) ;
423449 }
424450
425451 // Check if this item requires qualifiers
0 commit comments