title: ConditionalWeakTable still holds references that should be GC collected?
body: <p>I'm using <code>ConditionalWeakTable</code> for the purpose of loosely holding references instead of strongly referencing using a traditional lookup like <code>Dictionary</code>. 
  However I've tested one case to double-check that capability and looks like it's failed. The following code is based on <code>Windows Forms</code> however you can try adjusting it using any framework or platform you want:</p>
  
  <p><strong><em>The sample models</em></strong>:</p>
  
  <pre><code>public class SampleModel : INotifyPropertyChanged {
     public event PropertyChangedEventHandler PropertyChanged;
     protected void OnPropertyChanged([CallerMemberName] string property = null)
      {
          PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
      }
      string _name;
      public string Name
      {
          get
          {
              return _name;
          }
          set
          {
              if(_name != value)
              {
                  _name = value;
                  OnPropertyChanged();
              }
          }
      }
  }
  </code></pre>
  
  <p><strong><em>Main code</em></strong>:</p>
  
  <pre><code>//at some class level scope
  BindingSource _bs;
  ConditionalWeakTable&lt;BindingSource, object&gt; _lookup = 
                            new ConditionalWeakTable&lt;BindingSource, object&gt;();
  
  public void Test(){
     _bs = new BindingSource();
     var item = new SampleModel();
     _bs.Add(item);
     _bs.ListChanged += (s,e) =&gt; 
     {
        MessageBox.Show("Failed! There is some memory leak");
     };
     _lookup.Add(_bs, new object());
     //here the old instance is not referenced by any variable
     _bs = new BindingSource();
     //try collecting all collectable things
     GC.Collect();
     GC.WaitForPendingFinalizers();
     //try changing the item's property
     //the old instance of BindingSource if not collected will still 
     //fire the ListChanged event and the handler will show a message box 
     //as you see above.
     item.Name = "some name";
  }
  </code></pre>
  
  <p>The testing app is built in Release mode to ensure that the GC works correctly.
  And the result is the message box always shows. 
  The expected result is no message box shown.
  Note that the <code>Test</code> method is run just once for each time running the testing app.</p>
  
  <p>Could you please explain something wrong here? </p>