だるろぐ

明日できることは、今日しない。

引数で匿名型を受け取る

string クラスのためにこんな拡張機能があれば便利かなぁ、と思った。指定した要素タグでソーステキストを括って、HTML タグを出力できる。

public static string Wrap(this string source, string element)
{
    return string.Format("<{1}>{0}</{1}>", source, element);
}

たとえば、

"これを強調してぇ".Wrap("strong")

<strong>これを強調してぇ</strong>

が得られる。でも、どうせなら class 属性なんかも指定したくなるよね、と思う。たとえばこんな感じかな。

public static bool IsNullOrEmpty(this string source)
{
    return string.IsNullOrEmpty(source);
}

public static string Wrap(
    this string source, string element, string @class = null)
{
    return @class.IsNullOrEmpty()
        ? string.Format("<{1}>{0}</{1}>", source, element)
        : string.Format("<{1} class=\"{2}\">{0}</{1}>", source, element, @class);
}

こうすると、

"これを強調してぇ".Wrap("span", "label label-warning")

<span class="label label-warning">これを強調してぇ</span>

が得られると思う。ここまでするのならば、ほかの属性なんかも指定できるようになった方が便利なはずだ。第二引数(拡張メソッドの第三引数)を匿名型にして、いろいろ受け付けられるようにしてみたい。

public static string Join(this IEnumerable<string> source, string delimitter)
{
    return string.Join(delimitter, source);
}

public static string Wrap(
    this string source, string element, object attributes)
{
    var text = attributes.GetType().GetProperties().Select(_ =>
    {
        var name = _.Name;
        var value = _.GetValue(attributes, null).ToString();

        if (value.IsNullOrEmpty())
            return string.Empty;
        else
            return string.Format("{0}=\"{1}\"", name, value);
    })
    .Where(_ => !_.IsNullOrEmpty())
    .Join(" ");

    return string.Format("<{1} {2}>{0}</{1}>", source, element, text);
}

(Select() のなかで continue 使えたら Where() 要らないのになぁ)

こんな感じで使える。

// a タグで囲う
title.Wrap("a", new { href = source, title = title, });

GetType() した後どうすればいいんだ、と思って、MSDN を彷徨ってしまった。