読者です 読者をやめる 読者になる 読者になる

いろいろ備忘録日記

主に .NET と Python絡みのメモを公開しています。

ComboBoxで突然OutOfMemoryExceptionが発生する事象について (NativeAdd, ToString, nullを返す)

C# winforms


私の周りで、変な現象が発生して結構ハマったのでメモメモ。
画面にて、コンボボックスがありまして、それに表示するデータを
設定している部分で

System.OutOfMemoryException はハンドルされませんでした。
Message=コンボ ボックスの項目が多すぎます。
Source=System.Windows.Forms
StackTrace:
場所 System.Windows.Forms.ComboBox.NativeAdd(Object item)

と表示されるようになってました。


コンボに設定していたデータの件数はわずか5件程度です。
OutOfMemoryExceptionが発生する訳ない状態でした。


んで、ちょっと調べてみると、以下のようなリソースを発見。


コンボボックスに設定しているデータで、ToStringをオーバーライドしており
それがnullを返す場合にこのパターンが発生する模様。


試しにサンプルコード書いてみたら、例外が発生しました。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      comboBox1.Items.Clear();

      //
      // エラーが発生: OutOfMemoryException: コンボ ボックスの項目が多すぎます。
      //
      //   ComboItemクラスのToStringにて、Nameプロパティの値をそのまま返すようにしているので
      //   ToString()が呼ばれるとnullが返る。
      //
      comboBox1.Items.Add(new ComboItem { Name = null,    Value = "" });
      // OK.
      comboBox1.Items.Add(new ComboItem { Name = "",      Value = null });
      // OK.
      comboBox1.Items.Add(new ComboItem { Name = "hello", Value = "world" });
    }
  }

  class ComboItem
  {
    public string Name  { get; set; }
    public string Value { get; set; }

    public override string ToString()
    {
      return Name;
    }
  }
}


これ、結構知られてる現象なんですかね・・。
いきなり、出てビックリしました。


================================
過去の記事については、以下のページからご参照下さい。