NT京都2015

3/22(日)に京都で行われた、ネタモノ系ものづくりの展示・交流会「NT京都2015」を見に行ってきました。
見に行ったのは今年で2回目です。

こういう技術の無駄遣いな集まりが大好きです。
内容を詳しく書きたいのですが、今週は仕事が忙しいため詳細はまた次回記載したいと思います。

C# プロパティスコープの変数

C#7の機能追加のお話です。

C#7ではプロパティのスコープ内のみで使用できる変数が定義できるようです。
これにより以下のように実装できるようになります。

■今までの実装
private string _myField;
public string MyProperty {
 get { return _myField; }
 set {
  _myField = value;
  NotifyOfPropertyChange(nameof(MyProperty));
 }
}

■C#7での実装
public string MyProperty {
 string myField;
 get { return myField; }
 set {
  myField = value;
  NotifyOfPropertyChange(nameof(MyProperty));
 }
}

今まではクラス外からは_myFieldが隠蔽できていましたが、クラス内では自由にアクセスでき、隠蔽できてませんでした。
今回の機能追加により、プロパティのGetとSetからしかアクセスできない変数が定義できるようになり、完全な隠蔽ができるようになります。
VB6のころからこの機能が欲しいと思っていたので、とてもうれしいです。

C# タブインデックス(タブオーダー)の自動設定

先週、C#ソフトのタブインデックスを久しぶりに自分で設定しました。
いつもは誰かにして貰っていたのですが、自分でするとものすごく面倒くさい。
これは人のする作業ではないと考え、自動化する方法を検討。
結果、ネットの情報を元に以下の拡張メソッドを作成しました。

public static void RefreshTabIndex(this Control ctl) {
 //子コントロールのタブインデックス更新
 foreach (Control child in ctl.Controls) {
  if (child.Controls.Count <= 0) continue;
  child.RefreshTabIndex();
 }
 //子コントロールの位置をもとにソートする
 var children = new List<Control>();
 foreach (Control child in ctl.Controls) {
  children.Add(child);
 }
 children.Sort((x, y) => {
  if (x.Top == y.Top) return x.Left.CompareTo(y.Left);
  return x.Top.CompareTo(y.Top);
 });
 //タブインデックスを設定する
 for (int i = 0; i < children.Count; i++) {
  if (children[i].TabIndex == i) continue;
  children[i].TabIndex = i;
 }
}

フォームのコンストラクタなどで、this.RefreshTabIndex()を実行すると、
コントロールの配置をもとに自動でタブインデックスが設定されます。

まだ使い始めた所なので、この方法ではうまくいかない場合があるかも知れませんが。
概ね思っている動作をしており、作業が楽になりました。

 

関数型言語拡張ライブラリ(Lang Ext)

C#用の面白そうなオープンソースライブラリが載っていたのでメモ。
InfoQの記事

このライブラリを使うとC#に関数型言語の言語拡張が行われるそうです。
自分はF#やScalaなどの関数型言語にあまり詳しくないので、どういうメリットが生まれるのか良く分かっていないのですが、このライブラリをきっかけに覚えたいと考えています。

Blend for Visual Studio 2015

次バージョンの開発ソフトVisual Studio 2015に付属するBlend(XAMLのUIデザインツール)の見た目がVSそっくりになるそうです。機能もインテリセンスやコードスニペットが追加され、VSと似た雰囲気になります。多分ベース部分の実装が共通化されたのだと思います。

しかし、まだVSと統合はされておらず残念です。コーディングとUIデザインを完全にシームレスに行えるのは、さらに次のバージョンになるのでしょうか。

楽天のデータSIMカード

現在契約している楽天のデータSIMカード(月額900円)の高速通信容量の変更があり、今まで1G/月までだったのが2G/月までになりました。ありがたい。

このSIMカードを4ヶ月くらい使っていますが、1G/月を越えたことは
無かったので、当分はこのSIMカードで充分みたいです。

C#からEXCELファイルを読み書き

以前にC#などの.netアプリケーションからEXCELファイルの読み書きを行う方法として、Open XML SDKというマイクロソフトが公開しているライブラリについて記載しました。http://www.infortec.co.jp/blog/archives/Item_453

今回、ある案件でEXCELファイルを保存する処理が必要になったためOpen XML SDKを使用してみました。が、とても分かりにくい!使いにくい!

どうもEXCELのファイル形式であるOpen XMLに対する低レベルな実装しか無いようで、なんとも泥臭い。自分でラッパーを作れば使い物になるかも知れないが、そんな時間は無い。

しかたがないので、いつものようにEXCELをCOM参照して開発しようかと思ったが、ネットで調べると、EPPlusというライブラリを発見。

試して見ると、とても使いやすい。雰囲気的には今までのEXCELのCOMオブジェクトを正しく進化させ.netで扱いやすくした感じ。 すばらしい。

[2014.10.22 追記]
残念ながらEPPlusの使用は断念しました。
理由は、EXCEL COMオブジェクトの全機能をカバー出来ておらず、実現出来ない 機能があるからです。
出来なかったのはグラフのデータ系列の色・太さ・マーカ等の変更、グラフの目盛線の表示有無の変更など。
単に自分が探しきれなかったからかも知れませんが、 EXCELであれば、「マクロの記録」を使用すれば必要な機能にたどり着けるので、探す手間も全然違います。
結局は、マイクロソフトが.netで扱いやすいEXCEL制御クラスを用意してくれれば解決する話。なんとかならないのかな~。

スレッドセーフなコレクション

2つのスレッドで1つのコレクションを操作することが良くあります。

たとえば、1つのスレッドで測定値をコレクションに追加し続ける。
もう1つのスレッドでコレクションから測定値を取り出し、画面表示したり、ファイル保存したり。

C#のList<T>などのコレクションクラスはスレッドセーフではないので、
複数スレッドで操作する場合、操作する前にLockを行います。
しかし、Lockをするのはいちいち面倒ですし、間違ってLockせずに使用する不安もあります。

.Net3.0からはSynchronizedCollectionクラスなどスレッドセーフなコレクションが追加されています。
このコレクションを使用すると、AddやRemoveなどの単独操作はスレッドセーフになります。
しかし、ForEachなどの複合操作はスレッドセーフになりません。ですので不安が残ります。

結局、SynchronizedCollectionを内包し、スレッドセーフな操作しか行えないクラスを作成するのが一番良いかと考えています。
実装可能な操作はかなり限定されます。
AddかEnqueue、Clear、DequeueAll(全ての要素を取得してクリアする)、ToList、Count
こんなところでしょうか。
キューの操作しかできないので、クラス名はThreadSafeQueueにします。
スレッド間での複数要素の受け渡し用と割り切れば、役に立つのではないかと思います。

なお、List<T>のようにインデックスによる取得操作は実装できません。
指定したインデックスの要素が別のスレッドでRemoveされている可能性があります。
Dequeueも実装できません。
Dequeueした時には要素が1つも無い可能性があります。
TryGetやTryDequeueにして取得できたがどうかも戻せば良いかも知れません。