プログラミング C# - 翔ソフトウェア (Sho's)

C#/.NET/ソフトウェア開発など

Shos.CsvHelper (simple library for reading and writing CSV)

CSV Icon

I wrote a simple library for reading and writing CSV (the Values Comma-Separated or Character-Separated Values).

The csv format file is sometimes necessary because it can be displayed / edited with Excel and is simple. There are other libraries that read and write csv already, but I tried to make it simpler.

With this library, you can read and write plain object collections (IEnumerable<Something>) in csv format.

How to use

Overview of how to use

First, prepare something IEnumerable<TElement>:

    An IEnumerable<TElement> something
    IEnumerable<ToDo> toDoes = new ToDoList();

For example this class:

    class ToDoList : IEnumerable<ToDo> // sample collection
    {
        public IEnumerator<ToDo> GetEnumerator()
        {
            yield return new ToDo { Id = 1, Title = "filing tax returns", Deadline = new DateTime(2018, 12, 1) };
            yield return new ToDo { Id = 2, Title = "report of a business trip", Detail = "\"ASAP\"", DaySpan = new DaySpan(3), Priority = Priority.High };
            yield return new ToDo { Id = 3, Title = "expense slips", Detail = "book expenses: \"C# 6.0 and the .NET 4.6 Framework\",\"The C# Programming\"", Priority = Priority.Low, Done = true };
            yield return new ToDo { Id = 4, Title = " wish list ", Detail = " \t (1) \"milk\"\n \t (2) shampoo\n \t (3) tissue ", Priority = Priority.High };
        }

        IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
    }

You can write this as:

    const string csvFileName = "todo.csv";
    await toDoes.WriteCsvAsync(csvFileName);

The resulting csv file looks like this:

  • If the value contains commas, delimiters, newlines, or double quotes, these are enclosed in double quotes.
  • Double quotations in the value are replaced by two double quotations.
Id,Title,Deadline,Done,Priority,Details,DaySpan
1,filing tax returns,2018/12/01 0:00:00,False,Middle,,0
2,report of a business trip,2017/07/12 13:13:01,False,High,"""ASAP""",3
3,expense slips,2017/07/12 13:13:01,True,Low,"book expenses: ""C# 6.0 and the .NET 4.6 Framework"",""The C# Programming""",0
4, wish list ,2017/07/12 13:13:01,False,High," 	 (1) ""milk""
 	 (2) shampoo
 	 (3) tissue ",0

 

Open the created csv file in Excel
Open the created csv file in Excel

You also can read a csv file like this:

    IEnumerable<ToDo> newToDoes = await CsvSerializer.ReadCsvAsync<ToDo>(csvFileName);

Things to read and write

Public properties with both "get" and "set" of each element in the collection are read and written to csv files.

When writing:

When writing, it is converted to a string with the "ToString()" method regardless of the type.

When reading:

When reading, the string type is left as is, and enum (enumeration type) is read as the value of the string. For other types, it tries to change the string to a value using "TryParse" or "Parse". Types that cannot do either of these will not be read.

Properties that have both "get" and "set" and are of one of the following types are read:

  • String type
  • enum
  • A type that has a default constructor and can be "TryParse" or "Parse" (Basic numeric types such as int, DateTime, user-defined types with "TryParse" or "Parse")
Other rules
  • Properties with the [CsvIgnore ()] attribute are not read or written.
  • Properties with the [ColumnName("Column name")] attribute will be changed to the one with the specified column name in the csv file.

For example, the above ToDo class is like this:

    // Sample element type
    // Properties marked with ✔ will be read / written
    // Properties marked with ✖ won't be read / written
    class ToDo
    {
        public int      Id       { get; set; }                     // ✔
        public string   Title    { get; set; } = "";               // ✔
        public DateTime Deadline { get; set; } = DateTime.Now;     // ✔
        public bool     Done     { get; set; }                     // ✔
        public Priority Priority { get; set; } = Priority.Middle;  // ✔ user-defined enum 
        [ColumnName("Details")]
        public string   Detail   { get; set; } = "";               // ✔ [ColumnName ("Details")] changes the column name in the csv file to "Details"
        public DaySpan  DaySpan  { get; set; }                     // ✔ User-defined type with "Parse" (without "TryParse")
        [CsvIgnore()]
        public string   Option   { get; set; } = "";               // ✖ Ignored because [CsvIgnore()] is attached
        public string   Version => "1.0";                          // ✖ Ignored because it is only a get property
    }

The user-defined types used in the above ToDo class are as follows:

    // User-defined enum example
    enum Priority { High, Middle, Low }

    // Example of a user-defined type with "Parse" (without "TryParse")
    struct DaySpan
    {
        public int Value { get; private set; }

        public DaySpan(int value) => Value = value;
        public static DaySpan Parse(string text) => new DaySpan(int.Parse(text));
        public override string ToString() => Value.ToString();
    }

With or without header

csv can be read and written even if it has no header part (eg the first line of the csv file above).

However, if there is a header part, it can be read by collating the header part even if the column is switched, but if there is no header part, it cannot be read if the column is switched.

Example of writing without a header:

    await toDoes.WriteCsvAsync(csvFilePathName: csvFileName, hasHeader: false);

Csv file created:

1,filing tax returns,2018/12/01 0:00:00,False,Middle,,0
2,report of a business trip,2017/07/06 18:08:13,False,High,"""ASAP""",3
3,expense slips,2017/07/06 18:08:13,True,Low,"book expenses: ""C# 6.0 and the .NET 4.6 Framework"",""The C# Programming""",0
4, wish list ,2017/07/12 13:13:01,False,High," 	 (1) ""milk""
 	 (2) shampoo
 	 (3) tissue ",0

 

Open the created csv file in Excel
Open the created csv file in Excel

To read a csv file without a header:

    IEnumerable<ToDo> newToDoes = await CsvSerializer.ReadCsvAsync<ToDo>(csvFilePathName: csvFileName, hasHeader: false);    

Other specification methods

The character code can be changed (default is UTF8).

    CsvSerializer.Encoding = Encoding.GetEncoding(0);

The delimiter can also be changed (default is ',').

    CsvSerializer.Separator = '\t';

You can also use stream instead of file name.

    using (var stream = new FileStream(csvFileName, FileMode.Create))
        await collection.WriteCsvAsync(stream);

You can leave the stream open after reading or writing by specifying leaveOpen.

    using (var stream = new FileStream(csvFileName, FileMode.Create))
        await collection.WriteCsvAsync(stream: stream, bufferSize: 1024, leaveOpen:true, hasHeader: true);

In addition to asynchronous methods, there are also synchronous methods.

    toDoes.WriteCsv(csvFileName);

NuGet and GitHub

These libraries are open to NuGet and can be installed from Visual Studio.

Source code is available at:

The projects included are:

Shos.CsvHelper

  • CSV library
  • .NET Standard Library version
  • You can build a.NET Standard 1.3 and later
  • .NET Network 4.6 or higher, or.NET Core 1.1 or later for
  • NuGet packages that can be installed: NuGet Gallery | Shos.CsvHelper

Shos.CsvHelper.NetFramework

Shos.CsvHelperSample.NetCore

  • .NET Core Console applications that use the Shos.CsvHelper sample

Shos.CsvHelperSample.NetFramework

  • Using Shos.CsvHelper.NetFramework.NET Framework console application sample

最新の C#/.NET を使用するには (2019/09/25版)

※ 「.NET Core 3.0 正式版リリース」の続き。

先日 .NET Core 3.0 が正式にリリースされ、C# 8.0 が使えるようになった。
一方で、.NET Framework の最新版は 4.8 だ (2019/09/25 現在)。

現時点での、最新版の .NET を使用する方法をまとめてみよう。

.NET Framework 4.8 を使うには

下記からインストール。
※ Developer pack と Language pack の両方

.NET Core 3 で開発するには

Visual Studio Installer で Visual Studio 2019 Ver.16.3 以上にバージョンアップ

Blazor WebAssembly (クライアントサイド Blazor: プレビュー版) を試すには

最新版の Visual Studio に Blazor テンプレートのインストールが必要
次を参照

C# 8.0 で開発するには

プロジェクト ファイル (*.csproj など) に <LangVersion>8.0</LangVersion> を記述
(null 許容参照型も有効にするには <Nullable>enable</Nullable> も記述)

例.

  <?xml version="1.0" encoding="utf-8"?>
  <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      ...
      <PropertyGroup>
        ...
        <LangVersion>8.0</LangVersion>
        <Nullable>enable</Nullable>
        ...
    

 

.NET Core 3.0 アプリケーションのデフォルトの C# のバージョンは 8.0

参考資料

.NET Core 3.0 正式版リリース

.NET Core 3.0 正式版リリース

昨日 (2019/09/23)、.NET Core 3.0 正式版がリリースされた。

現在これに関連して、.NET Conf 2019 というオンライン カンファレンスが開催されている。
一部は、YouTube で見ることができる。

.NET Core 3.0

Microsoft 製の新たな .NET である .NET Core だが、.NET Core 3.0 では、Windows デスクトップ アプリケーション (Windows Forms と WPF) がサポートされた。

.NET Core 3.0 のためのソフトウェアの開発には、現在 Visual Studio 2019 の最新版である Ver.16.3.0 が必要だ。
Visual Studio Installer からアップデートできる。

但し、現在 .NET Core の Windows Forms のデザイナーには未対応であるようだ。

(なお .NET Core は、最初の .NET である .NET Framework に比べて様々な最適化がなされているため、より高パフォーマンスとなっている)

.NET Core の Roadmap

  • 2019/11 .NET Core 3.1 (LTS : Long Term Support 版)
  • 2020/11 .NET 5

.NET 5 は、.NET Core 3 の次期バージョンだ。

現在 3つある Microsoft .NET (.NET Framework, .NET Core, Xamarin) が 1 つに統合される予定。
これ以降、.NET Framework は保守のみとなり、新機能は追加されなくなる。

.NET Core 上の C++/CLI

C++/CLI .NET Core 3.1 でサポートされる予定だ。

Blazor

新たな ASP.NET (.NET での Web アプリケーション プラットフォーム) のフレームワークである Blazor だが、サーバーサイドの Blazor は、既に .NET Core 3.0 でサポートされている。

サーバーサイドの Blazor は、C# と Razor 構文でコーディングでき、クライアント サイドとの同期はフレームワークによって行われる (内部的には JavaScript を用いて SignalR で通信) という技術だ。

クライアント サイド Blazor (Blazor WebAssembly) は、WebAssembly で .NET が動作し、C# のアプリケーションがクライアント サイドの Web ブラウザ上で動作するというユニークなものだが、こちらは、現在まだ Preview 版。
2020年5月のリリースが予定されている。

C#

C#8.0 がリリースされた。
null 許容参照型や非同期ストリームなどがサポートされる。
非同期ストリームでは、非同期型の IEnumerable である IAsyncEnumerable が使われる。

関連記事

Microsoft MVP を再受賞しました (My 15th MVP Award from Microsoft)

MVP_Logo_Horizontal_Preferred_Cyan300_CMYK_72ppi.png

Microsoft MVP Award を再受賞しました。15年目になります。

My MVP Profile

いい歳の大人をこうして褒めてくれるマイクロソフトに感謝です。

Microsoft MVP となって、多くの素敵なITエンジニアの皆様との交流の機会が増えました。 皆様いつもありがとうございます。

de:code 2019 で C# ドキドキ・ライブコーディング対決をやってきました

MW51 | C# ドキドキ・ライブコーディング対決 @ de:code

毎年恒例の BuriKaigi などで4人でやっている C# ライブ コーディングセッションを Microsoftde:code 2019 でやってきました。

いつもお世話になっているマイクロソフトの井上章 (@chack411) さんのお誘いで実現したものです。 おかげさまでとても素敵な体験になりました。 もちろん、毎回楽しい企画をしてくださる石野 (@AILight) さん、一緒に解答者として登壇した鈴木 (@xin9le) さん、室星 (@RyotaMurohoshi) さん、にも感謝です。

今回は、Blazor を使用したプログラミングがお題で、次の2つをやりました:

  1. C# ライブ コーディング: その場で出たお題「C# で令和表示」を C#/Blazor で
  2. 七並べプログラム対決: 予め用意した「七並べのAI」を当日マージして対戦

「七並べ」対決の私の作戦は次の通りです:

99名の皆様が聴きにきてくださり、大変に盛り上がってくださいました。 本当にありがとうございました!

「MW51 | C# ドキドキ・ライブコーディング対決 @ de:code」 関連記事

当日の盛り上がりの様子の一部は、以下のリンクで読むことができます。

de:code 2019 関連記事

de:code 2019 の動画や資料などはこちらから。 (ただし、我々のセッションのものはありません)

NSAT

アンケート結果の NSAT (Net Satisfaction) がとても良かったので、メモ。

  NSAT
講師 198
コンテンツ 193
全体 195
参考: NSAT の求め方
  • Positive の比率 (パーセンテージ) = P
    • 4段階評価、5段階評価の場合: 1番上の評価をした人の比率
    • 10段階評価の場合: 1番上と上から2番目の評価の比率の合計
  • Negative の比率 (パーセンテージ) = N
    • 4段階評価の場合: 下2つの合計
    • 5段階評価の場合: 下3つの合計
    • 10段階評価の場合: 下4つの合計
  • NSAT = P - N + 100 (200点満点、平均100点)

Microsoft Build 2019 リンク集 (2019/05/07)

全般

一日目

全般

Azure

Office 365

.NET

ML

Visual Studio

Windows Terminal

WindowsLinux

その他

C# ドキドキ・ライブコーディング対決 @ de:code

MW51 | C# ドキドキ・ライブコーディング対決 @ de:code

毎年恒例の BuriKaigi などで4人でやっている C# ライブ コーディングセッションを Microsoftde:code 2019 でやります。