Interactive Extensionsを自分で実装する – 10.Hide, If, IgnoreElements

Interactive Extensionsを自分で実装する、第10回目はHideから。

まずは、使用例です。

static void HideTest()
{
    var sequence = new List<int>() { 0, 1, 2, 3, 4, 5 };
    var hideSequence = sequence.Hide();
    // cast original source
    try{
        IList<int> castToListSuccess = (IList<int>)sequence;
        Console.WriteLine("cast succeeded.");
    }
    catch (InvalidCastException ) {
        Console.WriteLine();
    }

    // cast hided sequence
    try{
        IList<int> castToList = (IList<int>)hideSequence;
    }
    catch (InvalidCastException){
        Console.WriteLine("Invalid cast.");
    }
    finally{
        foreach (var item in hideSequence){
            Console.WriteLine(item);
        }
    }
}

hide
正直このメソッド、利用価値がよくわかりません。おそらく具象クラスを完全に隠すことでユーザが暗黙の仮定を置いて危険なアップキャストをしていることを避ける目的があるのだと思いますが、それってどういうシチュエーションなんでしょうか。。では実装です。(Let’s Implement It!)

Hide…元シーケンスの実際の型を隠し、IEnumerable<T>のみを公開する

namespace EmulateInteractiveExtensions
{
    public static class EmulateIxExtensions
    {
        public static IEnumerable<TSource> Hide<TSource>(this IEnumerable<TSource> source)
        {
            if (source == null)
            {
                throw new ArgumentNullException();
            }
            foreach (var item in source)
            {
                yield return item;
            }
        }
    }
}

 

次はIfです。Ifのシグネチャは簡単。

static void IfTest()
{
    var sequence1 = Enumerable.Range(0, 3);
    var sequence2 = Enumerable.Range(0, 3);
    int i = 0;
    Func<bool> selector = () => i++ % 2 == 0;
    var ifSequnece = EnumerateEx.If(selector, sequence1, sequence2);
    foreach(var item in ifSequnece){
        Console.WriteLine(item);
    }
}

if
ちょっと気になったこととしては、御大層なメソッドな気がしたのでひょっとして列挙のたびにFuncデリゲート呼ばれてる?と思ったので、複数回呼び出されればそのたびに戻り値が変わるようにしたのですが、一度しか呼ばれてませんでした。ということで実装はシンプルにこんな感じ、Let’s Implement It!

If…Func<bool>デリゲートを取りシーケンス選択を遅延させる

namespace EmulateInteractiveExtensions
{
    public static class EmulateIxExtensions
    {
        public static IEnumerable<TResult> If<TResult>(Func<bool> condition, IEnumerable<TResult> thenSource)
        {
            return If(condition, thenSource, Enumerable.Empty<TResult>());
        }
        public static IEnumerable<TResult> If<TResult>(Func<bool> condition, IEnumerable<TResult> thenSource, IEnumerable<TResult> elseSource)
        {
            if (condition == null || thenSource == null || elseSource == null)
            {
                throw new ArgumentNullException();
            }
            return condition() ? thenSource : elseSource;
        }
    }
}

 

最後はIgnoreElementsです。使ってみます。

static void IgnoreElementsTest()
{
    IEnumerable<int> sequence = Enumerable.Range(0, 4);
    var result = sequence.IgnoreElements();
    foreach (var item in result)
    {
        Console.WriteLine(item);
    }
    Console.WriteLine("end");
}

ignoreelements
ダメです、もう完全に有難みがわかりません・・・。実装です。

IgnoreElements…アイテム列挙しない。

namespace EmulateInteractiveExtensions
{
    public static class EmulateIxExtensions
    {
        public static IEnumerable<TSource> IgnoreElements<TSource>(this IEnumerable<TSource> source){
            if(source == null){
                throw new ArgumentNullException();
            }
            return Enumerable.Empty<TSource>();
        }
    }
}
広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中