lookup interface implementation of "Add" method. Fixed bug #2980.
authorAtsushi Eno <atsushi@ximian.com>
Fri, 9 Mar 2012 05:43:24 +0000 (14:43 +0900)
committerAtsushi Eno <atsushi@ximian.com>
Fri, 9 Mar 2012 05:43:24 +0000 (14:43 +0900)
mcs/class/System.Xaml/System.Xaml.Schema/XamlTypeInvoker.cs

index ad1966235e8a886b80cb65a46b16f023734be1c1..756ddfbdf8fa76542ebcc3069090606cf887e44a 100644 (file)
@@ -81,14 +81,20 @@ namespace System.Xaml.Schema
                        }
 
                        if (mi == null) {
-                               if (ct.IsGenericType)
+                               if (ct.IsGenericType) {
                                        mi = ct.GetMethod ("Add", ct.GetGenericArguments ());
-                               else
+                                       if (mi == null)
+                                               mi = LookupAddMethod (ct, typeof (ICollection<>).MakeGenericType (ct.GetGenericArguments ()));
+                               } else {
                                        mi = ct.GetMethod ("Add", new Type [] {typeof (object)});
+                                       if (mi == null)
+                                               mi = LookupAddMethod (ct, typeof (IList));
+                               }
                        }
 
                        if (mi == null)
                                throw new InvalidOperationException (String.Format ("The collection type '{0}' does not have 'Add' method", ct));
+                       
                        mi.Invoke (instance, new object [] {item});
                }
 
@@ -98,10 +104,28 @@ namespace System.Xaml.Schema
                                throw new ArgumentNullException ("instance");
 
                        var t = instance.GetType ();
-                       if (t.IsGenericType)
-                               instance.GetType ().GetMethod ("Add", t.GetGenericArguments ()).Invoke (instance, new object [] {key, item});
-                       else
-                               instance.GetType ().GetMethod ("Add", new Type [] {typeof (object), typeof (object)}).Invoke (instance, new object [] {key, item});
+                       // FIXME: this likely needs similar method lookup to AddToCollection().
+
+                       MethodInfo mi = null;
+                       if (t.IsGenericType) {
+                               mi = instance.GetType ().GetMethod ("Add", t.GetGenericArguments ());
+                               if (mi == null)
+                                       mi = LookupAddMethod (t, typeof (IDictionary<,>).MakeGenericType (t.GetGenericArguments ()));
+                       } else {
+                               mi = instance.GetType ().GetMethod ("Add", new Type [] {typeof (object), typeof (object)});
+                               if (mi == null)
+                                       mi = LookupAddMethod (t, typeof (IDictionary));
+                       }
+                       mi.Invoke (instance, new object [] {key, item});
+               }
+               
+               MethodInfo LookupAddMethod (Type ct, Type iface)
+               {
+                       var map = ct.GetInterfaceMap (iface);
+                       for (int i = 0; i < map.TargetMethods.Length; i++)
+                               if (map.InterfaceMethods [i].Name == "Add")
+                                       return map.TargetMethods [i];
+                       return null;
                }
 
                public virtual object CreateInstance (object [] arguments)