PRB: "Ambiguous match found" Error Received When You Use the Default Collection Editor in Visual C# .NET (823194)



The information in this article applies to:

  • Microsoft ASP.NET (included with the .NET Framework) 1.0
  • Microsoft ASP.NET (included with the .NET Framework 1.1)

SYMPTOMS

You create a Web server control in Microsoft Visual C# .NET with a type-specific collection property and then put it on a Web page. When you edit the properties of the default collection editor and switch from Source view to Design view, or when you close and reopen the Web page, you may notice the following error message:
Parser Error: Ambiguous match found.

WORKAROUND

To work around the problem that is described in the "Symptoms" section of this article, modify the code of the ClassColl class that is described in the "More Information" section of this article.

Replace this code:
// This is the type-specific collection.
   public class ClassColl : System.Collections.CollectionBase 
   { 
      public int Add(ClassObj obj) { return List.Add(obj); } 
      public void Insert(int index, ClassObj obj) { List.Insert(index, obj); } 
      public void Remove(ClassObj obj) { List.Remove(obj); } 
      public bool Contains(ClassObj obj) { return List.Contains(obj); } 
      public void CopyTo(ClassObj[] array, int index) { List.CopyTo(array, index); } 

      public int IndexOf(ClassObj obj) 
      { 
         foreach (ClassObj r in List) if (r.Equals(obj)) return List.IndexOf(r); 
         return -1; 
      } 

      public ClassObj this[int index] 
      { 
         get { return (ClassObj)List[index]; } 
         set { List[index] = value; } 
      } 

      public ClassObj this[string index] 
      { 
         get { return (ClassObj)List[IndexOf(new ClassObj(index))]; } 
         set { List[IndexOf(new ClassObj(index))] = value; } 
      } 
   } 
With this code:
   // This is the modified type-specific collection.
   public class ClassColl : System.Collections.CollectionBase 
   { 
      public int Add(ClassObj obj) { return List.Add(obj); } 
      public void Insert(int index, ClassObj obj) { List.Insert(index, obj); } 
      public void Remove(ClassObj obj) { List.Remove(obj); } 
      public bool Contains(ClassObj obj) { return List.Contains(obj); } 
      public void CopyTo(ClassObj[] array, int index) { List.CopyTo(array, index); } 


      public int IndexOf(object obj) 
      { 
         if (obj is int)
            return (int)obj;

         if (obj is string)
         {
            for (int i = 0; i < List.Count; i++)
               if (((ClassObj)List[i]).ObjectString == obj.ToString()) 
                  return i;
            return -1; 
         }
         else 
         {
            throw new ArgumentException("Only a string or an integer is permitted for the indexer.");
         }
      } 

      public ClassObj this[object obj]
      {
         get { return (ClassObj)List[IndexOf(obj)]; } 
         set { List[IndexOf(obj)] = value;} 
      }
   } 

STATUS

This behavior is by design.

MORE INFORMATION

Steps to Reproduce the Behavior

Create a Web Server Control

  1. Start Microsoft Visual Studio .NET.
  2. On the File menu, point to New, and then click Project.
  3. In the New Project dialog box, click Visual C# Projects under Project Types, and then click Web Control Library under Templates.
  4. In the Name box, type ControlSampleLibrary.
  5. In the Location box, type c:\test.
  6. Rename the project file WebCustomControl1.cs as SampleControl.cs.
  7. Replace the default implementation of the control with the following code:
    using System;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.ComponentModel;
    
    namespace ControlSampleLibrary
    {
       // This is my object class.
       public class ClassObj 
       { 
          private string _ObjectString; 
    
          public string ObjectString 
          { 
             get { return _ObjectString; } 
             set { _ObjectString = value; } 
          } 
    
          public ClassObj() { _ObjectString = string.Empty; } 
          public ClassObj(string s) { _ObjectString = s; } 
    
          public override bool Equals(Object obj) 
          { 
             if (obj==null || GetType() != obj.GetType()) return false; 
             if (ObjectString!=((ClassObj)obj).ObjectString) return false; 
             return true; 
          } 
    
          public override int GetHashCode() 
          {
             int x = 0;
             return 	x;       
          }
       } 
    
       // This is the type-specific collection.
       public class ClassColl : System.Collections.CollectionBase 
       { 
          public int Add(ClassObj obj) { return List.Add(obj); } 
          public void Insert(int index, ClassObj obj) { List.Insert(index, obj); } 
          public void Remove(ClassObj obj) { List.Remove(obj); } 
          public bool Contains(ClassObj obj) { return List.Contains(obj); } 
          public void CopyTo(ClassObj[] array, int index) { List.CopyTo(array, index); } 
    
          public int IndexOf(ClassObj obj) 
          { 
             foreach (ClassObj r in List) if (r.Equals(obj)) return List.IndexOf(r); 
             return -1; 
          } 
    
          public ClassObj this[int index] 
          { 
             get { return (ClassObj)List[index]; } 
             set { List[index] = value; } 
          } 
    
          public ClassObj this[string index] 
          { 
             get { return (ClassObj)List[IndexOf(new ClassObj(index))]; } 
             set { List[IndexOf(new ClassObj(index))] = value; } 
          } 
       } 
    
    
       // This is the Web server control.
       [ToolboxData("<{0}:SampleControl runat=server></{0}:SampleControl>")] 
       public class SampleControl : System.Web.UI.WebControls.WebControl 
       { 
          private ClassColl _Col = new ClassColl(); 
    
          [Category("Things")] 
          [PersistenceMode(PersistenceMode.InnerProperty)] 
          public ClassColl Col 
          { 
             get { return _Col; } 
          } 
    
          protected override void Render(HtmlTextWriter output) 
          { 
             output.Write(this.ToString()); 
          } 
       } 
    
    }
    
  8. To build the solution, click Build Solution on the Build menu. Controlsamplelibrary.dll is created in the C:\Test\ControlSampleLibrary\bin\Debug\ folder.

Create a Web Application

  1. Start Visual Studio and create an ASP.NET Web application by using Visual C#.NET. By default, WebForm1.aspx is created.
  2. On the Build menu, click Build Solution.

Add Your Control to the Toolbox

  1. On theTools menu, click Customize Toolbox. In Visual Studio .NET 2003, click Add/Remove ToolBox Items on the Tools menu.
  2. Click the .NET Framework Components tab.
  3. Click Browse, and then locate the folder that contains the ControlSampleLibrary.dll file. Select the file, and then click Open.
  4. Click OK.
  5. Add a SampleControl to WebForm1.aspx.
  6. Right-click ControlSampleLibrary.SampleControl, and then click Properties.
  7. Click (Collection).
  8. To add objects to the collection, click Add in the Collection Editor.
  9. Click OK.
  10. Right-click WebForm1.aspx, and then click View HTML Source.
  11. Right-click Source View, and then click View Design.
  12. You notice the error message that is described in the "Symptoms" section of this article.

REFERENCES

For more information, visit the following Microsoft Developer Network Web site: For additional information, click the following article number to view the article in the Microsoft Knowledge Base:

324301 HOW TO: Create a Web Control with an Expandable Property in the Designer by Using Visual C# .NET


Modification Type:MajorLast Reviewed:8/6/2003
Keywords:kberrmsg kbCollectionClass kbWebServer kbprb KB823194 kbAudDeveloper