2014年9月25日木曜日

[C#]複製可能読み取り専用リスト

嵌ったのでメモ


タイトルの通り、読み取り専用だが複製(ディープコピーで作成されたインスタンス)を作ることができるリストを作りたかった。
C#様々ならちょろっと書けると思ったら丸一日掛かった。別にC#で作るのが困難だったからではなく、単に知識が著しく不足していたせいだが。


まず、複製可能なListを作るのにいろいろと発見があった。
最初、丁寧に一つ一つforeachでコピーしていくという方法を思い浮かべていた。

public class CopyableList<t> : List<t>
{
    public CopyableList<t> Copy()
    {
        var result = new CopyableList<t>();
        foreach( var data in this )
        {
            result.Add(data);
        }
        return result;
    }
}

これで複製はちゃんとできるしなかなかシンプルだと思ったが、なんというかC#らしさが欠片もない。で、普通はどんな風に実装するのか調べたらこの実装が非常に美しかった。(下に引用)

public class CloneableList<T> : List<T>, ICloneable<CloneableList<T>> where T : ICloneable
{
    public CloneableList<T> Clone()
    {
        var result = new CloneableList<T>();
        result.AddRange(this.Select(item => (T) item.Clone()));
        return result;
    }

    object ICloneable.Clone()
    {
        return ((ICloneable<CloneableList<T>>) this).Clone();
    }
}

public interface ICloneable<T> : ICloneable where T : ICloneable<T>
{
    new T Clone();
}

ジェネリック、LINQなどなど、これぞC#といって文句ないだろう。
本題から少し逸れるが、ICloneableというインターフェースを初めて知ったのでこれもいろいろ調べたが、何とも悩ましい限りのインターフェースだった。
ジェネリック実装前に作成されたインターフェースなので当然ジェネリックは考慮されてない(なので上の人は自分でジェネリック対応インターフェースを定義しているわけだ)。
で、このインターフェースはCloneメソッドを提供しているのだが、この実装がシャローコピーかディープコピーかは実装側の自由となっている[1]。あくまでインスタンスのコピーを作るメソッドということらしい。当然こんなインターフェースを外部に公開出来るはずもなく、APIなどにICloneableを使わないでくれと開発者直々にお達しが出されている[2]


Listを書き込み不可にする場合、AsReadOnlyメソッドで書き換え不可にするんだよなとか、でもそれだと一見普通のListと区別がつかないんだよなとか思ってたら、IReadOnlyListなんてまさに求めているものそのものが存在していた。こんな汎用性の高いインターフェースなんで知らなかったんだと思ったら、.NET 4.5で追加されたインターフェースだった(.NET 4.5が公開されてから既に2年が経っているが)。
IReadOnlyListのItemプロパティは読み取り専用で、AddメソッドやSortメソッドは定義されていない。
これでうっかり読み込み専用にしたListでAddメソッド呼び出して怒られるという悲劇からもおさらばだ。


ということで、複製可能読み取り専用リスト(のインターフェース)は次のように実装できる。

public class CloneableList<T> : List<T>, IReadOnlyCloneableList<T>, ICloneable<CloneableList<T>> where T : ICloneable
{
    public CloneableList<T> Clone()
    {
        var result = new CloneableList<T>();
        result.AddRange(this.Select(item => (T)item.Clone()));
        return result;
    }

    object ICloneable.Clone()
    {
        return ((ICloneable<CloneableList<T>>)this).Clone();
    }
}

public interface ICloneable<T> : ICloneable where T : ICloneable<T>
{
    new T Clone();
}

public interface IReadOnlyCloneableList<T> : IReadOnlyList<T>, ICloneable<CloneableList<T>> where T : ICloneable
{}

もっとスマートな実装が有るんだろうと思うけど、目的は叶ったしちゃんと動くし、全く問題はない。どのみちICloneableをなんとかしないかぎり自分用で使うし。


[1] http://msdn.microsoft.com/library/system.icloneable(v=vs.110).aspx
[2] http://blogs.msdn.com/b/brada/archive/2003/04/09/49935.aspx

2014年9月20日土曜日

わたる&おーみんのだらだら呑んで食べるだけ雑記#2



現代を生きる人々は、鹿を追いかけドングリを拾った頃と比べてあまりに生死の危機感に貧しいため、時に自らスリルを求めて生を実感するのではないか。
例えば、辛いものを食べることである。

上記の主張は色々と苦しいが、しかし、人間が他の動物と違って辛いものを好んで食べようとするのは、食べ物に余裕があることと、辛いものを楽しむ複雑な知性があるからだろうと私は思う。
となると、人間に次ぐ知性を持つと言われるゾウやイルカなどは、そのうち動物園や水族館で来場者に暴君ハバネロや激辛ペヤングを要求したりするのだろうか。

そんな杞憂を思いながら、私たち二人は秋葉原へ来た。
今回の標的は、『担々麺』である。

因みに、担々麺は本来「擔擔麵」と表記される四川料理を代表する一品で、19世紀の成都で天秤に麺と調理器具を担(擔)いで売り歩いたことを起源[1]とする、労働者向けのジャンクフードである。
当時の清の労働者たちも、きっとこの美辛い肉味噌餡の乗った麺を啜って英気を養っていたのだろう。
そうした歴史に思いを馳せつつ担々麺を食べると、意欲や元気が湧いてくるのは気のせいだろうか。我ながらなんとも都合のいい思考回路だと思いつつ。



19時を過ぎた頃、靖国通りと新幹線が交差する高架下に構えるその店は、小じんまりながらも存在感があった。
今回訪れた「雲林坊(ユンリンボウ) 秋葉原店」は、前を通れば誰もが目に止める、活気に満ちた店だ。

私たちが店内に入った時には既にお客さんで一杯だった。
店内はそこまで広くなく、カウンター10席が並ぶのみである。そう、これでいいのだ。仕事帰りのサラリーマンがカウンターで麺を無心に啜る。これこそ都心のラーメン屋だ。
しかし店内は清潔感もあり、決してむさ苦しい男の溜まり場という雰囲気でもない。実際、私たちが店を訪れたときも女性客は少なくなかった。この誰でも気楽に立ち寄れる雰囲気は素晴らしい。ただし、3人以上の団体での入店は難しいだろう。私たち2人でぎりぎりだったので。

私たち二人が注文したのは「汁なし担担麺」(¥830-)。
品書きには汁ありもあるが、今回はこの汁なしが目当てだ。
本場中国のスタイルに倣ったと言えば格好付くが、残念ながら関係ない。
この頃、高橋は長年愛してきたつけ麺にマンネリを感じているようだったが、遂にこの夏担々麺に心移りした。つけ麺に代わり日夜追い求めているらしい。
しかし、その担々麺の「汁なし」に拘るあたり、まだつけ麺への未練がたらたらなのが高橋らしさだ。

注文の回転率は高く、席に着いてから約10分、丁度良いタイミングで注文の品が出てくる。
まずその見た目、椀の形に目を見張る。アシンメトリーの白い器はまるで現代美術のオブジェか何かにしか見えない。しかし、その白磁の椀が麺を実に美味そうに色を引き立てるのだ。
そんな視覚に次いで、程なく嗅覚に刺激が走る。
花椒や八角などの香辛料がふんだんに掛けられており、椀を目の前に置くとすぐに中華らしいスパイシーで豊かで複雑な香りに包まれる。
この時点で期待は高まるばかりである。

麺を一口啜ると、もう素晴らしい。
麺に絡まった辛味の効いた肉餡とスープは、辛味をはっきり主張しつつ決して舌がヒリヒリするまではいかない。その奥に広がる肉とダシの旨味が辛味を抑えてくれる。いや、辛味と旨味が互いに見事に調和しているのだ。そして更にそこに香辛料の香りが口一杯に広がると、そこにはまさに中華のシンフォニーが生まれる。複雑で、優雅で、激しいハーモニーだ。
中太麺は食感、歯ごたえに存在感はあるが決して自己主張せず、肉餡とスープと香辛料をしっかりと引き立てている。
また、端に添えられた小松菜は色といい味といいまさに清涼剤のような存在だ。味付けはほとんどされていないが、麺を啜る合間に口に頬張ることで旨味がより一層引き立つ。
もう一つの引き立て役が、大量にまぶされたアーモンドだ。辛味の効いた餡と上手く中和して辛味を損ねることなくマイルドな風味になる。

細かい心配りも非常に感心した。
レンゲには3種類あり、白い陶器製のレンゲ(恐らく汁あり用)、そして金属製のレンゲには普通のと穴あきの二種類ある。辛味の強い汁が得意でない人には痛み入る配慮だろう。私たちのように得意な人は、普通のレンゲで最後の汁一杯まで堪能してほしい。

今回残念だったのは、白飯を注文しなかったことだ。
周りの客を見ていると、半数以上の人がご飯や麻婆丼などのセットで注文していた。個人的に麺とご飯を一緒に食べることをあまりしないので気に留めなかったのだが、汁なし担担麺を食べているうちにこれが非常にご飯に合うことに気付いてしまった。
もっと早く気づいていれば途中注文もできただろうが、麺を啜るのに夢中になってしまったのが敗因だ。
また、辛いのが苦手な人は卵を一緒に注文するといいだろう。これもまた非常に相性がいいだろうと途中で気付いた。

皿の底まで平らげて店を後にした私たちは、いかにあの店の担々麺が旨かったかを語り合っているうちに気付けば上野まで歩いていたのだった。
その後、HUB上野昭和通り店で3時間を呑み過ごして危うく終電を逃すところだったのだがそれはまた別の話。



人生は常に移ろい変わる。
いよいよ長かった学生生活に終わりが見え、社会へ歩み出す時が来た。
HUBで高橋の人生プランを聞いているうちに、お互い部を去って長い月日が経ったのだと感じずにはいられなかった。

思えばこの食べ歩きも随分遠くまで来たものだ。
ただ、ここまでだらだら続いたのだから、人生に変わらないものを持っておくのも悪くないだろう。



今回のお店はこちら。
『雲林坊 秋葉原店』
(食べログ) http://tabelog.com/tokyo/A1310/A131002/13141638/


#1 / 次 #2


[1] http://ja.wikipedia.org/wiki/担担麺#中国の担担麺