[Mono-bugs] [Bug 42547][Nor] New - Reflection does not bind to the best method.

bugzilla-daemon@rocky.ximian.com bugzilla-daemon@rocky.ximian.com
Wed, 7 May 2003 18:58:31 -0400 (EDT)


Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.

Changed by tom@acquist.com.

http://bugzilla.ximian.com/show_bug.cgi?id=42547

--- shadow/42547	Wed May  7 18:58:31 2003
+++ shadow/42547.tmp.26662	Wed May  7 18:58:31 2003
@@ -0,0 +1,148 @@
+Bug#: 42547
+Product: Mono/Class Libraries
+Version: unspecified
+OS: 
+OS Details: 
+Status: NEW   
+Resolution: 
+Severity: 
+Priority: Normal
+Component: CORLIB
+AssignedTo: mono-bugs@ximian.com                            
+ReportedBy: tom@acquist.com               
+QAContact: mono-bugs@ximian.com
+TargetMilestone: ---
+URL: 
+Cc: 
+Summary: Reflection does not bind to the best method.
+
+Description of Problem:
+Reflection method lookup will bind to an exact match if one is found, but 
+if one is not found, it will simply use the first match it finds.  It 
+should use the best possible match.
+In other words, if there are two methods, one that takes an object, and 
+another that takes a System.Array, and you're looking up a method for a 
+strongly typed string[], the System.Array method should match, but the 
+method that takes the object may be returned instead.
+It appears to be related to the order in the file in which the methods 
+appear.  The example below has two sets of identical methods, with the 
+second set declared in reverse order.  The example uses reflection to get 
+both methods with identical parameters, then calls them.
+
+
+Steps to reproduce the problem:
+Compile and run the following:
+
+using System;
+using System.Reflection;
+
+namespace MonoError
+{
+
+   public class BindingError
+   {
+   
+      public void Method(object thing)
+      {
+         Console.WriteLine("Method-Object version");
+      }
+
+      public void Method(Array thing)
+      {
+         Console.WriteLine("Method-Array version");
+      }
+
+      public void Method(string [] thing)
+      {
+         Console.WriteLine("Method-String [] version");
+      }
+
+      public void Method2(string [] thing)
+      {
+         Console.WriteLine("Method2-String [] version");
+      }
+
+      public void Method2(Array thing)
+      {
+         Console.WriteLine("Method2-Array version");
+      }
+
+      public void Method2(object thing)
+      {
+         Console.WriteLine("Method2-Object version");
+      }
+   
+
+      public static void Main()
+      {
+         object IntegerObject = 5;
+         object IntArrayObject = new int[] {5, 2, 5};
+         object StringArrayObject = new string [] {"One", "Two"};
+         object [] IntParam = new object [] {IntegerObject};
+         object [] IntArrayParam = new object [] {IntArrayObject};
+         object [] StringArrayParam = new object [] {StringArrayObject};
+
+         BindingError be = new BindingError();
+         Type betype = typeof(BindingError);
+
+         Console.WriteLine();
+         Console.WriteLine("Method 1:");
+         MethodInfo MI_Object = betype.GetMethod("Method", 
+Type.GetTypeArray(IntParam));
+         MI_Object.Invoke(be, IntParam);
+         MethodInfo MI_ObjectArray = betype.GetMethod("Method", 
+Type.GetTypeArray(IntArrayParam));
+         MI_ObjectArray.Invoke(be, IntArrayParam);
+         MethodInfo MI_StringArray = betype.GetMethod("Method", 
+Type.GetTypeArray(StringArrayParam));
+         MI_StringArray.Invoke(be, StringArrayParam);
+
+
+         Console.WriteLine();
+         Console.WriteLine("Method 2:");
+         MethodInfo MI2_Object = betype.GetMethod("Method2", 
+Type.GetTypeArray(IntParam));
+         MI2_Object.Invoke(be, IntParam);
+         MethodInfo MI2_ObjectArray = betype.GetMethod("Method2", 
+Type.GetTypeArray(IntArrayParam));
+         MI2_ObjectArray.Invoke(be, IntArrayParam);
+         MethodInfo MI2_StringArray = betype.GetMethod("Method2", 
+Type.GetTypeArray(StringArrayParam));
+         MI2_StringArray.Invoke(be, StringArrayParam);
+      }
+   }
+}
+
+
+Actual Results:
+In Mono 0.24:
+
+Method 1:
+Method-Object version
+Method-Array version
+Method-String [] version
+
+Method 2:
+Method2-Object version
+Method2-Object version
+Method2-String [] version
+
+
+Expected Results:
+In .Net 1.1:
+
+Method 1:
+Method-Object version
+Method-Array version
+Method-String [] version
+
+Method 2:
+Method2-Object version
+Method2-Array version
+Method2-String [] version
+
+
+How often does this happen?
+
+As it's due to the method layout in the file, intermittently.  This 
+example will reproduce consistently, however.