2010-11-29 9 views
1

私が手に例外がある:値はnullにすることはできません。これはなぜNull Value Exceptionを生成するのですか?

MyNamespace.Programのタイプ初期化子が例外に

を投げた内部例外は

メッセージを言います。パラメータ名:コレクション
出典: ... HashSetの...

これは、エラーは以下に示すライン上に発生していると信じて私をリード...

class Program 
{ 
    public static IEnumerable<char> WordCharacters = ExpandCharacterSet("A-Za-z0-9_"); 
    public static IEnumerable<char> NonWordCharacters = ExpandCharacterSet("^A-Za-z0-9_"); 
    public static IEnumerable<char> SpaceCharacters = ExpandCharacterSet(" \f\n\r\t\v"); 
    public static IEnumerable<char> NonSpaceCharacters = ExpandCharacterSet("^ \f\n\r\t\v"); 
    public static IEnumerable<char> DigitCharacters = ExpandCharacterSet("0-9"); 
    public static IEnumerable<char> NonDigitCharacters = ExpandCharacterSet("^0-9"); 
    public static IEnumerable<char> WildCharacters = ExpandCharacterSet("^\n"); 
    public static IEnumerable<char> AllCharacters = Enumerable.Range(0, 256).Select(Convert.ToChar).Where(c => !char.IsControl(c)); 

    public static IEnumerable<char> ExpandCharacterSet(string set) 
    { 
     if (set.Length == 0) 
      return ""; 

     var sb = new StringBuilder(); 
     int start = 0; 
     bool invertSet = false; 

     if (set[0] == '[' && set[set.Length - 1] == ']') 
      set = set.Substring(1, set.Length - 2); 
     if (set[0] == '^') 
     { 
      invertSet = true; 
      set = set.Substring(1); 
     } 
     set = Regex.Unescape(set); 

     foreach (Match m in Regex.Matches(set, ".-.|.")) 
     { 
      if (m.Value.Length == 1) 
       sb.Append(m.Value); 
      else 
      { 
       if (m.Value[0] > m.Value[2]) throw new ArgumentException("Invalid character set."); 
       for (char c = m.Value[0]; c <= m.Value[2]; ++c) 
        sb.Append(c); 
      } 
     } 

     if (!invertSet) return sb.ToString(); 

     var A = new HashSet<char>(AllCharacters); // <---- change this to "ABC" and the error goes away 
     var B = new HashSet<char>(sb.ToString()); 
     A.ExceptWith(B); 
     return A; 
    } 

    static void Main(string[] args) 
    { 
    } 
} 

しかし、私はドン理由は分かりません。

Console.WriteLine(string.Concat(AllChars)); 

期待どおりにすべての文字が印刷されます。だから、なぜHashSetはそれがnullだと思いますか?

+0

できません。問題を説明する簡単なプログラムを投稿できますか? –

+0

同上。 .NET 4.0で空のコンソールプロジェクトを作成しました。 'Main'に次の行を追加しました:' ExpandCharacterSet( "[^ abc]"); ';これは実際に行をヒットしますが、例外はありません。もう少しコードがあれば助けになります。 –

+0

あなたは正しいです...私は新しいファイルにそのコードを移動するときに私のために例外をスローしません。私はもう少し掘り下げてみましょう。 – mpen

答えて

5

私は、ExpandCharacterSetが別の静的フィールドを初期化するために使用されていると思います。 2つの静的フィールドを初期化する順序は保証されていないため、おそらくAllCharsを初期化する前に他のフィールドを初期化しようとしています。

割り当てを明示的な静的コンストラクタに、正しい初期化順序で移動してみてください。

例えば、あなたの現在のコードがある場合:

public static IEnumerable<char> AllChars = Enumerable.Range(0, 256).Select(Convert.ToChar).Where(c => !char.IsControl(c)); 
public static IEnumerable<char> Expanded = ExpandCharacterSet(...); 

ではなく、それを作る:再現する

public static IEnumerable<char> AllChars; 
public static IEnumerable<char> Expanded; 
static <ClassName> { 
    AllChars = Enumerable.Range(0, 256).Select(Convert.ToChar).Where(c => !char.IsControl(c)); 
    Expanded = ExpandCharacterSet(...); 
} 
+0

あなたは完全なコードを見ることなくそれを捕まえた方法を驚かせます。あなたはプログラミングの神でなければなりません! – mpen

+0

+1あなたはよく推測しています;-) – digEmAll

+0

+1:また、私は自分の答えを削除しました:)あなたはそれを非常にきちんと考えました。 – TalentTuner

0

次の2行のコードに基づいて、私は何も得られません。例外をスローしているコード行はどこにありますか?上記の2つの方法が正常に動作しているように見えるので、

public static IEnumerable<char> AllChars = Enumerable.Range(0, 256) 
              .Select(Convert.ToChar) 
              .Where(c => !char.IsControl(c)); 

var A = new HashSet<char>(AllChars); 
0

私が思うに、AllCharsは、あなたのコードのいくつかの他の部分からnullに設定されています。

実装の詳細を教えてください。

関連する問題