深く考えもせず、こんな感じのコードを書いていました。
public void SetValidChars(CharType type, string option) { var validChars = new List<char>(); if (type == CharType.AllAscii) validChars.AddRange(Enumerable.Range(0x20, 0x7f - 0x20) .Select(n => Convert.ToChar(n))); else if (type == CharType.NumericOnly) validChars.AddRange("0123456789"); else if (type == CharType.Optional) validChars.AddRange(option); // この後、validCharsを使ってごにょごにょ }
コンパイルかけて、UTも通して、さてと、とコードを眺めていたら、文字を眺めていてゲシュタルト崩壊起こしたときのように、なんだか急に不安になってきて、『…なんでこのコードコンパイル通るんだっけ?』。なんでList<char>.AddRange()にstringを引き渡せるんだっけ?
念のため「List<T>.AddRange」のオーバーロードを確認してみようとググってみたら、パラメータに「IEnumerable<T>」を受け付けるモノのみ。ふーん。やっぱそうだよね。
じゃあ、stringクラスのほうで「IEnumerable<char>」への暗黙の変換とかができるのかな?と思い、まずはstringクラスの型の構文をググって調べてみた。
ふーん。「IEnumerable」と「IEnumerable<string>」なのか。それだと「IEnumerable<char>」には勝手に変換できないよな。じゃあ、stringクラスに「IEnumerable<char>」に暗黙的に変換できるImplicitなオペレータがあるんだろう。と思って探してみたけど、…ない。…うん。そんなの見た覚えない。
もうわからん。なんか僕が知らない型変換の仕組みでもあるのか?と軽くパニックになりかけたところで、
『ん?stringクラスがIEnumerable<string>を実装?』。いったい何を列挙すんだよ、それ?
よくよくググった結果を見てみると、「.net Framework 2.0」と書いてある。まさかなー。と思いながら「.net Framework 4.5」に切り替えてみると、
public sealed class String : IComparable, ICloneable, IConvertible, IComparable<string>, IEnumerable<char>, IEnumerable, IEquatable<string>
わぁ。やっぱり「IEnumerable<char>」じゃねーか。じゃぁ、「2.0」バージョンでの説明が間違ってたんだよね。と、ちょっとほっとした。
…一応フィードバックを書いといたよ。
0 件のコメント:
コメントを投稿