スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: スポンサー広告

クロージャを作った。

言語仕様から読み解くC# 3.0入門
関数を返す関数、メソッドを返すメソッド、一般的(?)にクロージャと呼ばれるらしい。
上のリンクにも例があるけど、まあ、加算器のようなクロージャを返すメソッドを作る。

using System;

namespace TawamureDays {

/// <summary>
/// 戯れるクロージャ用クラス
/// </summary>
public static class TawamureClosure {

/// <summary>
/// カウントアップ用クロージャを取得します。
/// </summary>
/// <param name="start">開始の値</param>
/// <param name="step">増加値</param>
/// <returns>クロージャ</returns>
public static Func<int> CountUp(int start = 0, int step = 1) {
var i = start;

return () => {
try {
return i;
} finally {
i = i + step;
}
};
}
}
}

使うときは、こんな感じかな

IList dataList = ...;
var countUp = TawamureClosure.CountUp(0);

foreach (var data in dataList) {
var idx = countUp();
//...
}

クロージャを使わなければ、こんなかんじか?


IList dataList = ...;
var idx = 0;

foreach (var data in dataList) {
//...
idx ++;
}

これでよくね?とか思うときも多々ある。まあ、役割以外の事ができないので、他のものに間違って流用するミスが少なくなるかな。
通常のクラスは、データに対してメソッドがあるけど、クロージャはその逆で、メソッドに対してデータがあると考えたほうがいいかな。
試しに作ってみたクロージャの中でまだ使えるかな?と思ったのが、集計系のクロージャ。

using System;
using System.Collections.Generic;
using System.Linq;

namespace TawamureDays {

/// <summary>
/// 戯れるクロージャ用クラス
/// </summary>
public static class TawamureClosure {

/// <summary>
/// 指定リストの特定プロパティの値を集計するクロージャを取得します。
/// </summary>
/// <typeparam name="TItem">リストの要素の型宣言</typeparam>
/// <param name="selector">要素からdecimal型の値を取得するセレクタ</param>
/// <returns>指定リストの特定プロパティの値を集計するクロージャ</returns>
public static Func<IEnumerable<TItem>, decimal> SigmaDecimal<TItem>(
Func<TItem, decimal> selector) {
Func<TItem, decimal> decSelector = selector;

return srcList => {
if (srcList == null) {
return decimal.Zero;
}

decimal total = decimal.Zero;

foreach (var item in srcList) {
total = decimal.Add(total, selector(item));
}

return total;
};
}
}
}

リストの要素は別にdecimalでも、decimal以外でも良い。下のようなクラスがあったとする。

/// <summary>
/// 製品情報クラス
/// </summary>
public class Products {

/// <summary>
/// 在庫数量
/// </summary>
public decimal Stock {
get; set;
}

/// <summary>
/// 出荷済み数量
/// </summary>
public decimal ShippedVal {
get; set;
}
}

SigmaDecimalを使って、在庫数量(Stock)を集計するクロージャを作成する。

public void CalcStock() {

var sigmaStock = SigmaDecimal<Products>(p => p.Stock);

var products = new Products[] {
new Products {Stock = 132.22M, ShippedVal = 30.0M},
new Products {Stock = 125.12M, ShippedVal = 3M},
new Products {Stock = 56.9M, ShippedVal = 0M}
};
var allStock = sigmaStock(products);

var products2 = new Products[] {
new Products {Stock = 42.22M, ShippedVal = 440.0M},
new Products {Stock = 65.82M, ShippedVal = 33M},
new Products {Stock = 123.88M, ShippedVal = 12M}
};
//再利用
allStock = sigmaStock(products2);
return;
}

集計系のロジックなんぞは、メソッド化できるようでなかなかできない。
まあ、そういう時にクロージャ化すれば、ある程度は共通化できるかな。
スポンサーサイト
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: C# | コメント: 0 | トラックバック: 0


この記事へのコメント

コメントの投稿

非公開コメント


サイドバー背後固定表示サンプル

当ブログに書かれたソースコードは流用自由です。

バグ、スペルミス等はありうる事です。

ご利用の際は自己責任でお願いしますm(_ _)m

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。