StringConverterCreateNonNullable Method

Creates a new TypeConverter<String> instance.

Definition

Namespace: FolkerKinzel.CsvTools.Mappings.TypeConverters
Assembly: FolkerKinzel.CsvTools.Mappings (in FolkerKinzel.CsvTools.Mappings.dll) Version: 1.1.0+1263e8243dc2cd78095f678f813d7d9c52ea4315
C#
public static TypeConverter<string> CreateNonNullable(
	string defaultValue = ""
)

Parameters

defaultValue  String  (Optional)
The value of DefaultValue. The defaultValue must not be null.

Return Value

TypeConverterString
The newly created TypeConverter<String> instance. Its DefaultValue will be Empty.

Example

  Note

In the following code examples - for easier readability - exception handling has been omitted.

Exporting CSV data to Excel:

C#
using FolkerKinzel.CsvTools;
using FolkerKinzel.CsvTools.Mappings;
using System.Globalization;
using System.Text;
// A namespace alias helps to avoid name conflicts
// with the converters from System.ComponentModel
using Conv = FolkerKinzel.CsvTools.Mappings.TypeConverters;

namespace Examples;

internal sealed record Customer(string Name, decimal Sales, DateOnly RecentPurchase);

internal static class ExcelExample
{
    internal static void CsvDataExchangeWithExcel(string filePath)
    {
        // Which field separators and formatting Excel accepts and exports depends on the
        // "Regional Settings" in Excel. The default setting corresponds to the settings
        // of the user's computer (and thus of CultureInfo.CurrentCulture).

        // Using CultureInfo.CurrentCulture, the corresponding parameters can be determined
        // automatically.

        // The application is free to override the value of CurrentCulture for the current
        // Thread if users do not use the default setting in Excel.

        // This example shows the procedure for exporting CSV data to Excel. The procedure
        // for importing is equivalent.(The console output is from a computer with the locale
        // "de-DE".)

        Console.WriteLine("Current culture: {0}", CultureInfo.CurrentCulture);

        Customer[] customers = [ new("Susi", 4_711m, new DateOnly(2004, 3, 14)),
                                 new("Tom", 38_527.28m, new DateOnly(2006, 12, 24)),
                                 new("Sören", 25.8m, new DateOnly(2011, 8, 27)) ];

        // Get the Excel arguments for CultureInfo.CurrentCulture:
        (char delimiter,
         IFormatProvider formatProvider,
         Encoding ansi) = Csv.GetExcelArguments();

        // Pass the formatProvider from the Excel arguments to all localizable converters.
        // (The same CsvMapping can be used for writing and parsing.)
        CsvMapping mapping = CsvMappingBuilder
            .Create()
            .AddProperty("Name", Conv::StringConverter.CreateNonNullable())
            .AddProperty("Sales", new Conv::DecimalConverter(formatProvider))
            .AddProperty("RecentPurchase", new Conv::DateOnlyConverter(formatProvider))
            .Build();

        static void FillMapping(Customer customer, dynamic mapping)
        {
            mapping.Name = customer.Name;
            mapping.Sales = customer.Sales;
            mapping.RecentPurchase = customer.RecentPurchase;
        }

        // Don't forget to pass the delimiter from the Excel arguments!
        // (The textEncoding can be omitted when writing, but not when reading.)
        customers.SaveCsv(filePath, mapping, FillMapping, delimiter, textEncoding: ansi);

        Console.WriteLine();
        Console.WriteLine(File.ReadAllText(filePath, ansi));

        // =================================================

        // Parsing CSV that comes from Excel:

        static Customer InitializeCustomer(dynamic mapping) => new(mapping.Name,
                                                                   mapping.Sales,
                                                                   mapping.RecentPurchase);

        // Using this method allows to switch automatically to Unicode if the file
        // has a byte order mark, and to detect a different delimiter character if 
        // the user had changed the default settings in Excel.
        using CsvReader<Customer> reader = CsvConverter.OpenReadAnalyzed(filePath,
                                                                         mapping,
                                                                         InitializeCustomer,
                                                                         defaultEncoding: ansi);

        Console.WriteLine();
        Console.WriteLine("The customer with the lowest sales is {0}.",
                          reader.MinBy(x => x.Sales)?.Name);
    }
}

/*
 Console output:

Current culture: de-DE

Name;Sales;RecentPurchase
Susi;4711;14.03.2004
Tom;38527,28;24.12.2006
Sören;25,8;27.08.2011

The customer with the lowest sales is Sören.
*/

Object serialization with CSV:

C#
using FolkerKinzel.CsvTools;
using FolkerKinzel.CsvTools.Mappings;
using System.Text;
// A namespace alias helps to avoid name conflicts
// with the converters from System.ComponentModel
using Conv = FolkerKinzel.CsvTools.Mappings.TypeConverters;

namespace Examples;

internal sealed record Pupil(string? Name, string? Subject, DayOfWeek? LessonDay, TimeOnly? LessonBegin);

internal static class ObjectSerializationExample
{
    public static void CsvReadWritePupils(string filePath)
    {
        Pupil[] pupils = [
                            new("Susi", "Piano", DayOfWeek.Wednesday, new TimeOnly(14, 30)),
                            new("Carl Czerny", "Piano", DayOfWeek.Thursday, new TimeOnly(15, 15)),
                            new("Frederic Chopin", "Piano", null, null)
                         ];

        // A converter can be reused for more than one DynamicProperty:
        Conv::TypeConverter<string?> stringConverter = Conv::StringConverter.CreateNullable();

        // Initialize a CsvMapping that maps the data from the CSV-Columns and converts it to the right data type.
        // Aliases with wildcards can be used to match the column-headers of the CSV file. 
        CsvMapping mapping = CsvMappingBuilder
            .Create()
            .AddProperty("Name", ["*name"], stringConverter)
            .AddProperty("Subject", ["*subject", "*fach"], stringConverter)
            .AddProperty("LessonDay", ["*day", "*tag"], new Conv::EnumConverter<DayOfWeek>().ToNullableConverter())
            .AddProperty("LessonBegin", ["*begin?"], new Conv::TimeOnlyConverter().ToNullableConverter())
            .Build();

        // Create a CSV-File:
        pupils.SaveCsv(filePath,
                       mapping,
                       static (pupil, mapping) =>
                       {
                           mapping.Name = pupil.Name;
                           mapping.Subject = pupil.Subject;
                           mapping.LessonDay = pupil.LessonDay;
                           mapping.LessonBegin = pupil.LessonBegin;
                       },
                       columnNames:
                       ["Unterrichtstag", "Unterrichtsbeginn", "Vollständiger Name", "Unterrichtsfach"]);

        Console.WriteLine(File.ReadAllText(filePath));
        Console.WriteLine();

        // Read the CSV file:
        using CsvReader<Pupil> pupilsReader =
           CsvConverter.OpenRead<Pupil>(filePath,
                                        mapping,
                                        static mapping => new Pupil(mapping.Name,
                                                                    mapping.Subject,
                                                                    mapping.LessonDay,
                                                                    mapping.LessonBegin));
        pupils = [.. pupilsReader];

        // Write the results to the Console:
        foreach (Pupil pupil in pupils)
        {
            Console.WriteLine(pupil);
        }
    }
}

/*
Console output: 

Unterrichtstag,Unterrichtsbeginn,Vollständiger Name,Unterrichtsfach
3,14:30:00,Susi,Piano
4,15:15:00,Carl Czerny,Piano
,,Frederic Chopin,Piano

Pupil { Name = Susi, Subject = Piano, LessonDay = Wednesday, LessonBegin = 14:30 }
Pupil { Name = Carl Czerny, Subject = Piano, LessonDay = Thursday, LessonBegin = 15:15 }
Pupil { Name = Frederic Chopin, Subject = Piano, LessonDay = , LessonBegin =  }
*/

See Also