vaguely

和歌山に戻りました。ふらふらと色々なものに手を出す毎日。

C# 6の String interpolation で遊ぶ

はじめに

最近ついうっかり Effective C# Edition 3 を読み始めました。

その第4項目で、 string.Format() ではなく String interpolation を使いましょう、というものがありました。

C# 6.0 から、以下のように書けるようになったとのこと(なお Unity でも C# 6.0 を使用可能にすれば問題なく動作します)。

// 今まで.
string outputTextLegacy = string.Format("Hello {0}", DateTime.Now.ToString("yyyy-M-d dddd"));
Console.WriteLine(outputTextLegacy);

// 6.0以降.
string outputTextNew = $"Hello {DateTime.Now:yyyy-M-d dddd}";
Console.WriteLine(outputTextNew);

...うむ、後者を初見だと何やってるかわからないだろうな\(^o^)/

初見だとわからないなら何度も見れば良いじゃない

という声が聞こえましたので、ちょっと触ってみることにしました。

書き方

$"Hello {DateTime.Now:yyyy-M-d dddd}"

を紐解くと、頭に $ をつけて、文字列として置き換えたい部分を {} でくくり、
フォーマットの形式は : 以降に書きます。

なおフォーマット形式がない場合はデフォルトの形式で出力されます。

また : 以降はすべてフォーマットの形式を指定する文字列として扱われるため、 } との間にスペースなどを入れるとコンパイルエラーとなります。

試す

String interpolation 扱えるものは、先程の DataTime.Now のように値をそのまま書くことも可能ですし、
変数やメソッドも使用できます。

またIDEであれば入力補完もバッチリです( Visual Studio2017 + ReSharper 、 Rider で確認)。

変数を使う

double pi = Math.PI;
// 出力結果: 3.14
string outputTextNew = $"{pi:F2}";
Console.WriteLine(outputTextNew);

メソッドを使う

static void Main(string[] args)
{
    // Mainメソッドから呼び出しているためstaticにしているが、普通のメソッドでも使用可能.
    string outputTextNew = $"{GetMessage()}";
    Console.WriteLine(outputTextNew);
}
private static string GetMessage()
{
    return "Hello";
}
  • ただし当然とも言えますが、戻り値が void のメソッドはコンパイルエラーとなり使用できません。

三項演算子を使う

三項演算子を使う場合は少しだけ注意が必要です。

string test = null;
var outputTextNew = $"{(test == null ? "text is null" : DateTime.Now.ToString("yyyy-M-d dddd"))}";
  • 上記のように、式を () でくくる必要があります。

raw文字列を使う

例えばURLを扱う場合など、 @ をつけたい場合は、 $ の後につけます。

var outputTextNew = $@"URL: {"http://example.com"}";

Linqを使う

普通に使えるようです。

ただ、あんまりやりすぎると可読性、という面から厳しそうですが。

List textSample = new List
{
    "text1",
    "text2"
};
var outputTextNew = $"{textSample.Select(t => t).Count().ToString()}";
Console.WriteLine(outputTextNew);

async / await

当然ながら使えません。

{} のエスケープ

$ をつけている場合、 {} が全て

$"Hello World! {{nullText ?? \"text is null\"}}";

その他注意点

これも Effective C# で取り上げられている内容ですが、これを使ってSQL文を組み立ててはいけません。

SQLインジェクションを避けるため、これまで通りプレースホルダーを使用する必要があります。

おわりに

今までの方法と比較して、 String interpolation を使うことでセットする文字列の、
順番や数の間違いなどを防げる、という利点に加えて処理がグッとシンプルに書けそうなので良いと思いました。

ただ途中でも書きましたが、あまりごちゃごちゃやり過ぎると見づらくなったりバグの原因になりそうなので、
ほどほどにしておくのが良さそうですね。

参照

dotnetConf 関西2017に参加してきました

はじめに

10/14に日本マイクロソフト関西支店で行われた、dotnetConf関西 2017に参加してきました。

connpass.com

4セッション + LT大会で、バラエティ豊かな内容を聴くことができました。

聴き逃しや勘違いなどもあるかとは思いますが、聴きながら書き留めたメモを中心に書き残しておきます。
(修正などはご指摘いただければ対応します)

またスライドは後から公開されたものがあればリンクを追加する予定です。

.NETの今と未来~デバイス&クラウドネイティブを目指して

dotnetConfについてや、セッションのタイトル通り15年前!に登場した.NETが今どう変わっているか、今後どのように進んでいくか、
ということが紹介されました。

※このスライドは東京で行われたdotnetConf 2017の時のものです。
内容は少し更新されていたように思いましたが、参考のため載せておきます。

www.slideshare.net

ここからメモ


dotnetConfについて

dotnetConfはオンラインが中心。ただし今回のようにローカルイベントも世界各地で行われている。

channel9.msdn.com

Twitterでの盛り上がりはマイクロソフト本社にも伝わる。そのためどんどんツイートしてほしいとのこと。

マイクロソフト社の活動としてはAzureがメインになってきている。
ただし.NETは.NETで変わらず活動していく。

.NET Framework、.NET Core

Windows上で動作する .NET Framework (現行ver.4.7)と、
マルチプラットフォームで動作する .NET Core (現行ver.2.0。ベースの一部はMono)。

これらは今後も統合されるようなものではなく、それぞれ進化していく。

ただし.NET Frameworkの資産を .NET Core、 Xamarin でも活用できるように、
共通化( .NET Standard ?)も進めていく。

実装は C# がメインであり、最初に実装されはするが、 VB.net 、 F# もしっかりサポートしていく( .NET Framework、 .NET Core 共に)

Xamarin

Xamarinには2種類の作り方がある。

  • Xamarin Native -> UI部分はそれぞれのプラットフォームに合わせて作り、共通処理をひとまとめ
  • Xamarin Forms -> UI部分から共通。ただしプラットフォームによって制限もあり?

どちらで開発するにしても、iOS開発にはXCodeが必要。

Xamarin Live Player を使うと、 Visual StudioiOSバイスをペアリング -> Visual Studio で Xamarin.iOSデバッグが可能。

ただし XCode でビルドした状態と全く同じ、というわけではないので最終出力する部分は MacXCode が必要。

.NET Standard

.NET Standard は、 .NET Framework 、 .NET Core 、 Xamarin で共通で利用できるコード。

ver.2.0で2万以上のコードが共通化された。

利用方法としては、共通化させたいコードを .NET Standard ライブラリとして切り出す -> ライブラリとして使用可能
( Nuget パッケージも同時作成)

Container + Docker

現在はCloud上にあらかじめ用意されている機能・サービスを活用していく Cloud Native が中心になってきた。

App service on Linux & Web App for Containers

今までベース部分のOSはWindowsだったが、Linux を使うものが登場した(App service on Linux)。

コンテナでランタイムを実装する -> コンテナさえ動くようにすれば、どこでも動かすことができるように

Write-once, Run-anywhere

Containerを使う上で必要なファイルも Visual Studio で生成・編集できるように。

Visual Studio 2017 では Docker を利用する機能が内包されている。
通常のビルドと同じような操作で Docker のビルドをすることができる。

Serverless

Azure Functions -> AWS の Lambda のような、Serverless を実現する機能。

Functions は Visual Studio で、 .NETC# を使って開発可能。

動作するのはユーザーからトリガーを引くための操作が行われた場合。

ローカルで動かしている.NETコードを基本そのままクラウドに上げることができる

よりモダナイズされた環境での開発・サービス提供を


ここまで

感想

.NET って本当に幅広いんだなぁ(こなみかん)

お話の中で特に気になったのは .NET Standard と Azure でした。

.Net Standard は、例えば自分の普段の作業では Unity と UWP で処理を共通化させる、といったことができそうです。

また、処理を共通化させることができる、という意味ではネイティブだけでなく、 Xamarin にも取り組んでみようかなぁ。

あと Azure はそれ自体も気になるところですし、 Functions も C# で書くのであれば、
AWS Lambda よりも情報を集めやすそうな気がします。
( AWS Lambda では C# がメインの言語ではないため、
他の言語の情報を変換する必要があると思うので)

お試し枠もあるようなので、こちらも近いうちに触ってみたいと思います。

Visual Studio拡張とRoslynとDotNet.exeなどいろいろ

Visual Studio拡張機能を作成した時にハマったあれこれが紹介されました。

10/16現在スライドがプライベートになってて見られないようなので、とりあえずトップのリンクを張っておきます。

www.slideshare.net

ここからメモ


拡張:Extensibility -> VSIXプロジェクト

下位互換性をもたせたい場合も、最新(Max ver)のVSで作成する

右クリックでメニューを追加したい場合、Custom Commandを追加し、実装する

ファイル名がすべてCommand名と共通のものになるため、全体に関連するファイルなどはリネームしたほうが良い

例)
  • RClickCommandPackage.vsct -> ExTest.vsct
  • RClickCommandPackage.cs -> ExTestPackage.cs

ドッキングウィンドウの追加は Custom Command Window?を使う

VS2017でしか使えないパッケージが含まれていてVS2015で使った瞬間クラッシュした


VS2015で作るとVS2017にはインストールできない

関数の型を調べるためにリフレクションを使おうとすると、VSがdllを開きっぱなしにしてしまい、
ビルド時?にエラー(Warning?)が出るので拡張を作る上では問題がある


ここまで

感想

Visual Studio を使って Visual Studio拡張機能を作成する、というのはまだツラいところがあるのだなぁ
(最新版の Visual Studio が出るたびにビルドし直す必要があったり、プロジェクトのテンプレートにゴミが入っていてエラーになったり)
というのが正直な感想ではあります(´・ω・`)

ただ、ここも今後改善されてはくるのだろうと思いますし、
やっぱり自分の使い方に合わせて機能を追加していけるのは良いと思うので、自分としても挑戦はしてみたいなぁ、とも思いました。

また、紹介されていた拡張機能も試してみたいところ。

.NET Standard入門

最初のセッションでも紹介された、 .NET Standard についてガッツリ紹介されました。

www.slideshare.net

ここからメモ


.NET Standard は、 .NET Framework 、 .NET Core 、 Xamarin のどれかだけにべったり依存したものではない。

一般的には可能な限り最小バージョンの .NET Standardを使うのが推奨される。

最適なバージョンは Visual Studio 側で静的に見てくれるわけではないため、
バージョン指定 -> コンパイル -> エラーが出たらバージョンを上げる
という作業を繰り返す必要がある。

実際にはライブラリを作るときに.NET standardが利用される。

  • Shared library - Assemblyを共有しない。共有プロジェクト(ソースコードレベルの共有)
  • PCL - 今はあまり使われていない
  • .NET Standard - Assemblyを共有

今後は .NET Standard を使うことが推奨される?

PCL は .NET Standardの各バージョンと互換性がある。
足りないものはNugetでとってきて解決する。

Visual Studio 2017 Update4 からは .NET Standard2.0 のインストールをしなくても使える、らしい。

dnSpyでデコンパイル

(dnSpyについてはこの辺が参考になりそう?)

https://qiita.com/NetSeed/items/54fbf30cb21c77c05c41

dllでは型が定義されているのではなく、 TypeForwardedTo でアトリビュートで指定されているだけ

同じString型でも、 WindowsAndroid などターゲットに応じて全く別のクラスを参照している
(違いは.NET Coreが吸収する)

最終的には .NET Core の Library を参照するわけだが、そこまでの過程はプラットフォームごとに異なっている。

Nuget Package を参照したクラス?ライブラリを参照した Console App を実行するとエラーでクラッシュする ↓ 実行時に必要なライブラリもファイルを移動しないため

ValueTuple は .NET Framework4.7 から使用できる。 ただし、4.6の場合も .NET Standard で定義してそれを読み込むと.NET Framework からでも使用できる。

ただし、dllファイルを大量に引き連れてきてしまうので注意。


ここまで

感想

自分の実力的に理解しきれなかったところがたくさんあった、
というのが正直なところですが、公開された資料やお話の中にあったキーワードを元に、
中身を追いかけていこうと思います。

また、ググった感じでは Unity で .NET Standard のライブラリを作る、利用する、といった情報は少ないようですが、
こちらも試したいところ。

Introducing Fluent Design System あるいは Metro の先を紡ぐ手がかり

スキューモーフィズムから Metro (Modern UI)を経て、
Hololens などの Mixed Reality などにも対応する、
Fluent Design について紹介されました。

ここからメモ


スキューモーフィズム -> Metro -> UWP(PCやスマホだけでなく、ラズパイやHololens)にも対応

Hololensの登場により、UIが画面の外に出てくるようになった

Fluent Design * Project Neon Fall Creates Updateで利用可能 * Light、Depth、Motion、Material、Scaleの5つの要素 * コンテンツが繋がっていくデザイン * 3D時代のWindowsのためのデザインシステム * フラットでもなく、スキューモーフィズムでもない、物質の本質を表現する

XamlでAcrylicBrush要素を使うことでアクリルブラシが使用可能に (アクリル板のように半透明になるイメージ)

Lightはマウスカーソルを光源?としてボタンなどにライトを当てることができる

MR Design Lab: UIサンプル

github.com

色遣いも決まりがある。

半透明とはいえ、Vista時代のものとは意味が異なっている


ここまで

感想

Fluent Design については、一番普段の仕事に近いのに全く知らなかったため、
早くキャッチアップせねば、という気持ちです(;´Д`)

最近(というほどでもないけど)登場したデザインとしては他に Material Design がありますが、
テイストなどは異なるものの、紙や光など自然界にあるものを表現する、
という部分に共通点があるのかな、などとぼんやり思いました。

LT

本編も濃ければLTも濃い。

あまり書き留めることはできませんでしたが、どれも聴きどころ満載な感じでしたw

- Manga-Yonda!!

www.slideshare.net

ここからメモ


XAML条件分岐 

今までは XAML の中で条件分岐を表現するのは難しかった

blog.tmyt.jp

現在は Conditional XAML を使うことで、条件分岐が使えるようになった。

が、制限はあり、C#でifを書くようには使えないっぽい

Xamarin

Xamarin NativeでもMVVMCrossなどを使うことでDataBindingが使える

Azure Machine LearningでCNNを使って二次元の顔判定

Azure Machine LearningではGUI機械学習ができる

学習に24時間以上かけられない、という制限がある

その他

www.instagram.com

なお懇親会にも参加させてもらいましたが、
持ち前のコミュ障を発揮してあまりお話することができずorz

ま、まぁこの辺は次回リベンジということで。

あとお話を聴いているだけでも楽しかった、ということは付け加えておきます。

おわりに

実は .NET 関連の勉強会は初めての参加でしたが、
参加されている方や雰囲気もどことなく違っていて新鮮でした。

.NET Standard や Azure など、気になる情報もたくさん得られたので、
時間はかかるかもですが一つずつ試してみようと思います。

スタッフの皆様、参加された皆様、会場やWifiなどを提供いただいたマイクロソフト様、ありがとうございました!

最後に...

【C#】Taskをキャンセルする

はじめに

前回に引き続き、async / await / Task ネタです。

非同期で処理している内容をストップするにはどうするの?というお話。

Task.Runの中で処理を止める

Task.Run の中で、条件に応じて処理を途中で止める、というのは比較的簡単です。

private async void CallAsyncMethod()
{
    var myTask = await GenerateTextAsync();
    // GenerateTextAsync() の処理が完了したら実行される.
    Debug.Log(myTask);
}
private async Task< string> GenerateTextAsync()
{  
  return await Task.Run< string>( () => {

    if(何かの条件)
    {
      return "Canceled";
    }
  

    Thread.Sleep( 3000 );
    const string sampleText = "Hello\nworld\nおはようございます!\n";

    return sampleText;
  } );
}

普通の処理と同じく、早期リターンするか後の処理を if でくくって Task を完了させてしまえば良いですね。

Task.Runの外から処理を止める

では Task.Run の外側から処理を止めるにはどうするか。

感覚的には Task.Cancel とかすれば良い気がしたのですが、そのようなメソッドはありません。

方法としては、
1. Task.Run の第二引数として、 CancellationToken という Token を渡します。 2. Task.Run の外側(処理を止めたいタイミングで) CancellationToken.Cancel() を実行します。 3. Task.Run のなかで CancellationToken.IsCancellationRequested が True かどうかを確認し、 True なら処理を止めます。

using UnityEngine;
using UnityEngine.UI;
using System.Threading;
using System.Threading.Tasks;

public class MainController : MonoBehaviour {
    public Text ResultText;
    private int flag;
    private void Start ()
    {
    
    // 非同期処理をCancelするためのTokenを取得.
        var tokenSource = new CancellationTokenSource();
        var cancelToken = tokenSource.Token;
        

        CallAsyncMethod(cancelToken);
        Debug.Log("Start()");

  
    // 処理をキャンセル.
        tokenSource.Cancel();
    

    }
    private async void CallAsyncMethod(CancellationToken cancelToken)
    {       
        var myTask = await GenerateTextAsync(cancelToken);
        Debug.Log(myTask);
    }
    private async Task GenerateTextAsync(CancellationToken cancelToken)
    {
        var context = SynchronizationContext.Current;

        return await Task.Run( () => {
            Thread.Sleep( 1000 );

        
            if (cancelToken.IsCancellationRequested)
            {
                Debug.Log("Canceled");
                // キャンセルされたらTaskを終了する.
                return "Canceled";
            }
      

            const string sampleText = "Hello\nworld\nおはようございます!\n";

            Thread.Sleep( 2000 );

            context.Post((state) =>
            {
                ResultText.text = sampleText;
            }, cancelToken);
            return sampleText;
        }, cancelToken);
    }
}

回りくどい気もしますが、 どのような処理を行っているかを確認せず、いきなり強制終了するな、ということなのではないでしょうか。

Token を、 GenerateTextAsync を呼んでいる CallAsyncMethod() ではなく、さらに上流となる Start() で生成・渡しているのは、
前回書いた通り await を使って非同期処理を呼ぶと、それ以後の処理は非同期処理が完了するまで実行されないためです。

なお、処理がキャンセルされたときに例外を投げたい場合は、 cancelToken.ThrowIfCancellationRequested() を使ってシンプルに書くことができます。

if (cancelToken.IsCancellationRequested)
{
  Debug.Log("Canceled");
  // キャンセルされたら OperationCanceledException を投げる.
  cancelToken.ThrowIfCancellationRequested();
}

注意すべき点としては、キャンセルされたときに処理を止める、という処理は自分で書かないといけない、という点です。
あくまでもキャンセルされたことが Task.Run の中で判別できるようにする、という仕組みのようなので。

おわりに

Task がキャンセルされうる、というのは引数に Token を渡すことで判断はできるのですが、
本当にキャンセル処理が含まれているか、というのは静的に確認できると良さそうな気はしました
(とはいえキャンセルフラグが立ったときに、必ずしもその場で処理をストップするとは限らないので難しいかもですが)。

まだちゃんと調べられてはいませんが、 Task は別の Task とまとめたりもできるようなので、
見通しが悪くならない程度に細分化して、必要な処理が揃っているかを確認する、というのが良いのかもしれませんね。

参照

【C#】Unityでasync / await

はじめに

Unity2017以降、C#6の機能を使うことができるようになりました。

今回のテーマである async / await はモバイル環境だとまだ課題があるようですが、
とにかく触ってみることにしました。というお話。

準備

Unity2017.1.1f1 時点では、 C#6 (というか .net 4.6)はデフォルトでは有効になっておらず、
Experimental という扱いになっています。

有効にするには、 Player Settings > Other Settings > Configuration > Scripting Runtime Version を、
Experimental(.Net 4.6 Equivalent) に切り替えて、 Unity Editor を再起動します。

非対応

…とここまでワクテカしながら読み進めてきた方がいましたら残念なお知らせなのですが、
Unity のクラス(というか MonoBehaviour を継承しているクラス)のメソッドは、
今まで通り MainThread 以外からの実行はできません。

後述しますが、 SendMessage や ExecuteEvents.Execute も、定義しているクラス自体は MonoBehaviour を継承していないものの、
別 Thread から実行するとエラーになります。
(おそらく最後、指定したメソッドを実行するところでエラーになっているのではないかと思います)

ということで、ファイルの読み込みや HttpClient など、時間のかかる、かつ C# の機能を使って行われる処理に対して使うことができる状況です。

なお UniRx と組み合わせるとより便利になりそうではあるのですが、
今回はそのまま使ってみることにします。

とにかくやってみる

ということでまずは使ってみましょう。

なお async / await / Task の使い方は参照のリンク先におまかせします(丸投げ)。

using UnityEngine;
using UnityEngine.UI;
using System.Threading;
using System.Threading.Tasks;

public class MainController : MonoBehaviour {
    public Text ResultText;
    private void Start ()
    {
        CallAsyncMethod();

    // CallAsyncMethod() を呼び終わったら(処理の完了を待たずに)実行される.
        Debug.Log("Start()");
    }

    private async void CallAsyncMethod()
    {
        var myTask = await GenerateTextAsync();
        // GenerateTextAsync() の処理が完了したら実行される.
        Debug.Log(myTask);
    }

    private async Task< string> GenerateTextAsync()
    {
    // 非同期処理を定義して返す.        
        return await Task.Run< string>( () => {
            // 三秒間だけ待ってやる.
            Thread.Sleep( 3000 );
            const string sampleText = "Hello\nworld\nおはようございます!\n";

            Debug.Log("GenerateTextAsync()");
            return sampleText;
        } );
    }
}
  • Task を返す GenerateTextAsync() を呼び出すとき、 await をつけ忘れて myTask.Result とかしてしまうと、
    Unity Editor がフリーズするので気をつけましょう。
  • Debug.Log が実行される順番は 1. Start() 2. GenerateTextAsync() 3. myTask ( GenerateTextAsync() の戻り値)です。
  • Debug.Log は Unity の処理ですが、別 Thread から呼び出しても特にエラーにはなりません。

async の Unity 定義メソッドへの適用

await をつけて GenerateTextAsync() を呼ぶためには、そのメソッドに async をつける必要があります。

これは Start() など Unity のメソッドにも適用できます。

ただし、非同期処理を呼んだ後の処理は(例: CallAsyncMethod() の Debug.Log() )、それが完了するまで呼ばれないため、
上記のように別のメソッドに切り分けたほうが良いと思います。

TaskからMainThreadを呼ぶ

さて、前述の通り、 GenerateTextAsync() の Task.Run< string> の中で ResultText (UnityEngine.UI.Text) のテキストを変更することはできません。

Task からこのような処理を行うにはどうすれば良いでしょうか。

Androidには別 Thread から UIThread を呼び出す方法があります。

mainActivity.runOnUiThread(new Runnable() {
    @Override
    public void run() {
        // MainThread での処理.
    }
});

これと同様の仕組みが、 C# にも存在します。

using UnityEngine;
using UnityEngine.UI;
using System.Threading;
using System.Threading.Tasks;

public class MainController : MonoBehaviour {
    public Text ResultText;
    private void Start ()
    {
        CallAsyncMethod();
  }

    private async void CallAsyncMethod()
    {
        var myTask = await GenerateTextAsync();
    }

    private async Task< string> GenerateTextAsync()
    {
    
    // MainThreadのコンテキストを取得.
        var context = SynchronizationContext.Current;
    

        return await Task.Run< string>( () => {
            Thread.Sleep( 3000 );
            const string sampleText = "Hello\nworld\nおはようございます!\n";


      // MainThreadのコンテキストを通して、Textを変更する.
            context.Post((state) =>
            {
                ResultText.text = sampleText;
            }, null);
      
            return sampleText;
        } );
    }
}

SynchronizationContext を使って MainThread のコンテキストを取得することで、
別 Thread から Unity の( MainThread からの実行が必要な)処理を実行することができます。

おわりに

C#6 の機能が使えるようになったことで、細かい部分でも色々便利になって良いですね☺

async / await は、将来的に Unity の処理にも使うことができるようになるのかはわかりませんが、
時間のかかる処理を行う場合には是非とも活用していきたいところです。

とりあえず非同期処理のかんたんなところに触れてみましたが、
もう少し突っ込んで触ってみたくもあります。

ということで、次回に続く。。。かもしれない。

参照

【C#】横書き -> 縦書き変換

はじめに

Twitterにてちょっと話題になった、テキストを縦書きで投稿するためのメモです。

今回はテキストを固定にしていますが、Unity、WPFなどで入力元、出力先を指定してやれば動的に生成したり、
Twitterなどにそのまま投稿することもできます。

縦に書く

TextViewなどの機能を使う場合は別ですが、
文字列を縦に並べるには単純に文字列を一文字ずつに区切って、それを縦に並ぶよう置き換えるのが良さそうです。

なお列の区切りは改行文字とします。

まずは一文字ずつに区切り、ついでに全角・半角文字が混ざると位置がずれてしまうので、半角文字の場合はスペースを追加することにします。

// 元のテキスト.
const string sampleText = "Hello\nworld\nおはようございます!\n";
// 改行文字で区切る.
var splittedSamples = sampleText.Split('\n');

// ToCharArray()で一文字ずつ切り出し -> charからstringに戻す -> 半角文字にスペース追加.
var results = splittedSamples.ToList()
    .Select(samples => samples.ToCharArray()
        .Select(sample => sample.ToString())
        .Select(sample => Regex.Replace(sample, @"[a-zA-Z0-9|\.\-\\\,]", " " + sample))
        .ToList()).ToList();

これで一文字ずつ切り出して、一行ずつにまとめた List< List< string>> の値となります。

なお、長音の縦横置き換えなどは行っていないため、必要に応じて追加してください。

あとはこれを頭から並べていきます。

const string sampleText = "Hello\nworld\naaa\nbbb\n";
            
var splittedSamples = sampleText.Split('\n');

var results = splittedSamples.ToList()
    .Select(samples => samples.ToCharArray()
        .Select(sample => sample.ToString())
        .Select(sample => Regex.Replace(sample, @"[a-zA-Z0-9|\.\-\\\,]", " " + sample))
        .ToList()).ToList();

var resultMaxCount = results.Select(samples => samples.Count).Max();

var resultText = "\n";
for (var i = 0; i < resultMaxCount; i++)
{
    for (var j = results.Count - 1; j >= 0; j--)
    {
        // 列の間に全角スペースをはさむ.
        resultText += "  ";
        // その列に文字がなかった場合は全角スペースに置き換え.
        resultText += (results[j].Count - 1 >= i) ? results[j][i] : "  ";
    }
    resultText += "\n";
}

せっかくなのでこちらも Linq で解決したいところでしたが、
良い方法が思いつかなかったのでfor文を使うことにしました。

また、Twitterに投稿する場合に、一行目の最初の文字より前に入っているスペースが取り除かれてしまうようです。
それを防ぐため、頭に改行を挟んでいます。

参考

C#で CSV -> Json を作る

はじめに

前回PythonでCSVからJsonを作るというのをやりましたが、
ふとC#(Unityではなく)でやってみたらどうなるんだろう、と思ったのでやってみました。

CSVを読み込む

CsvReader.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace CsvConverter
{
    public class CsvReader
    {
        public List ReadCsv()
        {
            using (var reader = new StreamReader(@"parts.csv", Encoding.UTF8))
            {
                var partsList = new List();
                // 1行目はスキップ.
                reader.ReadLine();
                    
                while (reader.Peek() > -1)
                {
                    var readText = reader.ReadLine();
                    if (readText == null)
                    {
                        continue;
                    }
                    var splitTexts = readText.Split(',');
                    if (splitTexts.Length < 3)
                    {
                        continue;
                    }
                    var newParts = new Parts
                    {
                        PartsNo = splitTexts[0],
                        PartsName = splitTexts[1],
                        Description = splitTexts[2],
                    };
                    partsList.Add(newParts);
                }
                return partsList;
            }
            return null;
        }
    }
}

Jsonファイルとして出力

Parts クラスのリストを Json に変換するには、UniRxでいつもお世話になっている neueccさんの DynamicJson を使用しました。

http://dynamicjson.codeplex.com/

シンプルな使い勝手ながら、しっかりとドキュメントも用意されていて大変ありがたい限りですm(__)m

唯一はまったのが、変換元のクラスの変数は、プロパティを持つ必要がある、ということです。

MetaParts.cs (失敗)

public class MetaParts
{
    public string ModelName;
    public List PartsList;
}
  • この場合、正しく変換できず空の Json ができてしまいます。

正しくは。。。

MetaParts.cs

public class MetaParts
{
    public string ModelName { get; set; }
    public List PartsList { get; set; }
}

変換自体は驚くほどに簡単です。

JsonCreator.cs

using System;
using System.IO;
using System.Text;
using Codeplex.Data;

namespace CsvConverter
{
    public class JsonCreator
    {
        public string Create(MetaParts parts)
        {
            // MetaPartsクラスのオブジェクトをJsonに変換して返す.
            return DynamicJson.Serialize(parts);
        }
        public void Output(string jsonText)
        {
            using (var writer = new StreamWriter(@"parts.json", false, Encoding.UTF8))
            {
                // Jsonファイルとして出力.
                writer.Write(jsonText);
            }
        }
    }
}

メインクラス

最後に、各クラスを呼び出すメインクラスです。

Program.cs

using System;
using System.Collections.Generic;

namespace CsvConverter
{
    internal class Program
    {
        public static void Main(string[] args)
        {
            var reader = new CsvReader();
            var partsList = reader.ReadCsv();

            if (partsList == null)
            {
                return;
            }
            
            var creator = new JsonCreator();
            var sampleMetaParts = new MetaParts
            {
                ModelName = "Model1",
                PartsList = partsList
            };
            var jsonText = creator.Create(sampleMetaParts);
            creator.Output(jsonText);
        }
    }
}

Deveropers.IO 2017 WORLD in 大阪に行ってきました

はじめに

9/23に梅田スカイビルで行われた、クラスメソッド社の方々によるDeveropers.IO 2017 WORLD in 大阪に行ってきました。

dev.classmethod.jp

内容は今年7/1に東京で行われた Deveropers.IO 2017 や、
大阪オフィスの方による計4セッションでした。

聞き漏らしたり間違って理解しているところもあるかとは思いますが、
思うままに書き留めておくことにします。
(各セッションの資料は公開してくれるとのことなので、公開された順にリンクを貼っていく予定です)

クラメソの請求を支える技術(サーバーレス編)

受注から納品後の請求処理までのやり取りをIT化したときの流れ、
見直した後の構成などを紹介する内容でした。

正直一番感じたのは、外から見てイケてる会社であっても、
手動だったりこなれていないところというのは残っているものなのだなぁ、ということでした。

どんな会社でも特に表に出づらい社内のやり取りなど、
どうしても置いてきぼりになりがちだとは思いますが、それをガッと大きく変えていけるところは強いなぁ、と感じました。

あと40代の生存戦略の話で、
例えばWebサービスを作るときにAPIやOAuth2.0などの深い知識と技術を身に着けて活躍する専門家になるのか、
それらの技術をパーツとして組み合わせ、糊付けしてWebサービスを作る人になるのかを決めることが大事。

(意訳)という話も印象的でした。

自分はどうしたいだろう。

何でも完璧にこなすスーパーマンになることができれば良いですが、
それはきっと難しい。

じゃあ何を選ぶのか。どうありたいか。

そんなことを考えさせられたセッションでした。

あとしがないOLさんって女性だったんだ…て

基礎からのOAuth2.0

OAuth2.0の解説、というのが内容の中心ですが、
まずは混同されがちな認証と認可の違いについてのお話から。

よくあるTwitterアカウントを使ってサービスの認証を行う、
というのはOAuthで行うことではない、という話。

これらの内容から、ではOAuth2.0は何をするものなのか、
処理の流れ(アカウントトークンの受け渡しなど)について、
ジョークも交えつつ (いや渋谷の女子高生とか本気かもしれませんが) 噛み砕いて解説されていました。

このセッションについては動画、スライドが公開されているため、
もう一度じっくり見返して理解していきたいところです。
(分かりづらかったのではなく、あまりに私の基礎知識がなさすぎた)

www.slideshare.net

www.youtube.com

クラメソのWebサイトを支える技術

Developers.IOブログなどのWebサイトの構成などを、
その特徴や利点などを交えながら紹介されました。

が、ちょっと私の知識が足りなさすぎて理解が追いつかなかったというのが本音のところです。。。

使用されているAWSのサービスなどについては、資料も見ながら一つずつ辿ってみたいです。

dev.classmethod.jp

Alexaで変わる開発、変わらない開発

Amazonによる、Echoなどのスマートスピーカーを操作することができるAlexaの紹介と、
シンプルな内容でAlexaを動作させるライブ開発、という内容でした。

ステートレスであるAWS Lambdaで、ステートフルな会話から必要なコマンドを拾っていく、
というのは確かに工夫が必要でしょうし、
画面に表示がなく、音声のみによる入力・フィードバックするUIもまだこれから、というところでしょう。

以前Umeda.apk(だったはず)で見たGoogle Homeや今回のAlexaなど、
どれか一つくらいは実際にも触ってみたいところ。

Echoは日本で使えるのはまだ先ですよね。。。

Google Homeは年末くらいに日本でも発売するらしいので、こっちを先に試してみても良さそう。

www.lifehacker.jp

あと開発の様子はGoogle HomeもAlexaも似通っているところがあって、
(揃えているのかもしれませんが)やっぱりこういうやり方が現時点では一番なのかな、とも思いました。

あと何より、ライブ開発、ライブコーディングは見てるだけでも緊張感ありすぎでしたwww

おわりに

楽しかったです。

自分の知識が足りなくて理解が追いつかなかったところも正直ありましたが、
そこはそれ。お話されていた内容をキーワードとして、少しずつ調べていきたいと思います。

やっぱり社内の技術的な内容(だけではないけど)を、
外部にも発信していけるというのは強いなぁ、とも感じました。

クラスメソッドの皆様、ありがとうございました!!