引数で匿名型を受け取る

執筆日時:

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=&quot;{2}&quot;>{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 を彷徨ってしまった。