ブログ「サイバー少年」

ブログ「サイバー少年」へようこそ!
小学六年生ごろからプログラミングを趣味にしている高校生のブログです。
勉強したことについての記事などを書いています。フリーソフトも制作、公開しています。
(当ブログについて詳しくは「ブログ概要紹介」を参照)

サイバー少年が作ったフリーソフトは「サイバー少年の作品展示場」へ

String.Containsメソッドの怪…!

C#にstring.Containsメソッドがありますよね。

このメソッドには引数がchar型のものがありますね。
つまり、

"あいうえお".Contains('あ');

みたいな。

また、引数がstring型のものもありますね。

"あいうえお".Contains("あああ");

みたいな。


先ほど、引数がchar型のほうのContainsメソッドを使ったコードを書いていました。

それで、しばらくして、
「using System.Linq; は要らないから消そう、Delキーポチッ」
というふうにSystem.Linqのusingを消したわけです。


すると、先ほど書いたコードのContainsメソッドを呼ぶ部分にエラーが!!

「'string.Contains(string)' に最も適しているオーバーロード メソッドには無効な引数がいくつか含まれています。」

なぜだオイイイ!!!

なんと、System.Linqのusingを消した途端、
string.Containsメソッドの定義が、引数がstringのほうだけになってしまったのです!


なんだこれは…、怪奇現象だ…。
調べてみて、謎が解決したのでメモします。




C#、というか.NET FrameworkにおけるSystem.String型は、

実はひっそりとIEnumerable<char>インターフェースを実装しています。

stringって実はcharの列挙としても使えたんですね…。


「じゃあIEnumerable<char>に引数がchar型のContainsメソッドが定義されていたってことか」

と思った方、違います。

確かにクラスがインターフェースのメンバを暗黙的に実装した場合は、
クラスのメンバとしても、インターフェースのメンバとしてもそれを参照することが可能です。

(明示的に実装した場合は、インターフェースではなくクラスとして扱っている限り、実装したメンバにアクセスすることはできないのです。)


しかし、それだとusingを消しても引数がchar型のContainsアクセス可能なはずですし、

そもそもIEnumerableはSystem.Collection.Genericsにあるのに、関係ないSystem.Linqのusingを消したらエラーが出たのです。




「ではSystem.Linqに犯人がいるのか…?」

そういうことでした。


実はSystem.Linq内のEnumerableというクラスが、引数がchar型のContainsメソッドを作り出していました。

Enumerableクラスには、Containsという名前のメソッドが定義されており、
それがIEnumerable<T>インターフェースの拡張メソッドとして働いていたようです。


それにより、IEnumerable<T>にはContainsというメソッドが追加され、

IEnumerable<char>を実装していたSystem.Stringにも伝わってきて、

"あいうえお".Contains('あ');

のような書き方が可能になったというわけです。

ですから、実はこれはEnumrableクラスのメンバを呼んでいるわけですね。


そして拡張メソッドは、その拡張メソッドが定義されているクラスを、
usingによって名前空間を省略できる状態にしないと認識されませんので、

System.Linqのusingを消したら引数がchar型のContainsメソッドにアクセスできなくなり、エラーになったというわけです。




凄いからくりなんですね…。


ちなみに、引数がstring型のContainsメソッドは、ただただ純粋にSystem.Stringクラスに定義されているメソッドなので、

System.Linqのusingを無くしてもアクセスできるというわけです。


最近のMicrosoftは拡張メソッドを多用しますが、いいことばかりではないと思いますね~。

tag:

コメント

コメントの投稿

トラックバック

トラックバック URL
http://cyberboy6.blog.fc2.com/tb.php/317-df8a4a45
この記事にトラックバックする(FC2ブログユーザー)

当ブログをご利用(閲覧等)になる場合は必ず「当ブログの利用規定」をお守りください。