No more Death March

あるSEのチラシの裏 C# WPF

既定のプリンター名を取得する。

using System;
using System.Printing;

namespace DefaultPrinterName
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("既定のプリンタは{0}です。", LocalPrintServer.GetDefaultPrintQueue().FullName);

            Console.ReadKey();
        }
    }
}

system.printingを参照設定に追加
LocalPrintServerクラスのstaticメソッドGetDefaultPrintQueueでプリンタ設定のインスタンスを取得
FullNameプロパティでプリンタ名を取得

WPFで帳票 参考リンク

ネットで色々検索してみるとWPFでも帳票印刷が出来るらしい。
後で参考に出来そうなリンクをメモ

以下参考:
WPFでの印刷の基本(1) 単一ページの印刷 - Qiita
WPFでの印刷の基本(2) 複数ページの印刷 - Qiita
WPFを帳票フレームワークとして使う - @kotyのブログ
WPF/XAMLで帳票のデザイン・印刷を行う - Qiita
[C#]プリンタ一覧と、デフォルトプリンタを取得するには
のぶろぐ WPFでの印刷

C# 月末日

public DateTime ToMonthLastDate(DateTime value)
{
    return new DateTime(value.Year, value.Month, DateTime.DaysInMonth(value.Year, value.Month));
}

年と月はそのまま、日にちだけDateTimeクラスのDaysInMonthメソッドに年と月を渡してやる。
VB6の時は翌月1日の前日という具合に算出していたけど、オーバーフローのチェックが必要になるのでこっちの方が良い。

インターフェースを考える(14)考えを整理(出来ていない)

C#実践開発手法のシングルメソッドインターフェースで色々書いてきたけども、
途中途中浮かんだ考えをだぁーっと箇条書きにしてみる。

  • 処理は小さく、抽象化されており、組み換え可能であることが望ましい。
  • シンプルな処理であればあるほど、コードを修正する可能性は低くなる。
  • 小さいクラスは設計・開発・テストのサイクルがシンプルで作業を理解しやすい。
  • コードに修正の余地が無ければ、たった一つでも仕事をしていれば資産と言える。
  • コードを修正して機能を増やすことよりクラスを増やして機能を増やしていく。
  • クラス数が増えるのは問題ではない、増えたクラスがライブラリや名前空間で整理されていないのが問題。
  • 複数の処理を持っているクラスはその分コードを修正する可能性が高くなる。
  • 修正の可能性が低いコードほど堅牢で修正の可能性が高いコードほど脆弱なコードになる。
  • 10の機能を持った1つのクラスを作るなら、1つの機能を持ったクラスを10個つくれば良い。
  • 具体的な処理は不変であり、コラボレーション部分のみが修正の対象となれば良い。
  • 分岐を目的としたパラメータを持つメソッドはパターン毎にメソッドを分割出来るはず。
  • 条件分岐はパターン毎の処理を実行するという責務と、パターン毎に振り分けを行うという責務に分離する。
  • シングルメソッドインターフェースは構造化プログラミングとOOPのポリモーフィズムのおいしいとこ取りをしている。
  • 複数の処理を持ちたければ振る舞いクラスに委譲すれば良い。
  • インターフェースのみに依存する場合、またはクラスに依存していても行き着く依存先がインターフェースのみであれば静的クラスの利用も悪くない。
  • 何かを呼び出して戻り値を受け取る処理はまた別ななにかを呼び出して依存する。戻り値が必要無いように組み替えれば余計な依存関係は生まれない。
  • プログラムの仕様変更が入った時のことを想像する。それがそのまま責務を分割する糸口になる場合がある。
  • 思い切ってクラスの継承は無いものと考えた方が設計が捗る。
  • ドメインモデル・ドメインオブジェクトは人の理解を促すために組み立てるもの。と考える。具体的な処理は小さくて組み換えやすいクラスに委譲する。

インターフェースを考える(13)コレクションとインターフェース

IActionやISpecificationなど、単一の要素に対するインターフェースでしたが、
実際にアプリケーションを組むとなると必ずコレクションに対する操作が必要になると思います。

今回は拡張メソッドを使って、都度コーディングをしなくてもこれらインターフェースの処理を使い回す方法を考えます。

まずIActionについて、以下のような拡張メソッドを用意しました。

        public static void DoEach<T>(this IEnumerable<T> actors,IAction<T> action)
        {
            new List<T>(actors).ForEach(x => x.Do(action));
        }

        public static IEnumerable<T> DoEachFluent<T>(this IEnumerable<T> actors, IAction<T> action)
        {
            actors.DoEach(action);
            return new List<T>(actors);
        }

やっていることは単純でListクラスのForEachメソッドにIActionを実行する匿名メソッドを指定しているだけです。

同じようにISpecificationを使った拡張メソッドをIEnumerableに追加します。

using System.Collections.Generic;

namespace Nmdm.Specifications
{
    public static class ISpecificationExtension
    {
        public static IEnumerable<T> FindAll<T>(this IEnumerable<T> collection,ISpecification<T> spec)
        {
            return new List<T>(collection).FindAll(x => spec.IsSatisfiedBy(x));
        }
    }
}

こちらも同じ要領でListのFindAllメソッドにboolを返す匿名メソッドを指定しているだけ。

どちらもやっていることはデリゲートを使うメソッドをインターフェースに適用させてるだけですね。

C#実践開発手法でもコードに適用力を持たせるならデリゲートよりクラスですよと書いてあるけど、
それなら標準のデリゲートと同じようにインターフェースも用意してあれば良かったのになぁ・・・