[Mono-list] Bug fix - 41691

B Anirban banirban@novell.com
Mon, 08 Dec 2003 21:30:28 -0700


Hi,
I am posting here my fixes for bug 41691.
For this I felt a need for changing the check_type method (in
Binder.cs) for extracting  better match. Hence I created here a
overloaded version of check_type method.
Also I overloaded the SelectMethod function for handling named
arguments.
I am attaching the test cases for the same as well. 
Looking forward for your suggestion on this implementation.
Regards.
Anirban.

===================================================================
RCS file: /mono/mcs/class/corlib/System/MonoType.cs,v
retrieving revision 1.49
diff -u -r1.49 MonoType.cs
--- class/corlib/System/MonoType.cs	1 Aug 2003 14:59:42
-0000	1.49
+++ class/corlib/System/MonoType.cs	28 Nov 2003 21:02:17 -0000
@@ -299,7 +299,7 @@
 			if ((invokeAttr & BindingFlags.SetField) != 0 &&
((args == null) || args.Length != 1))
 				throw new ArgumentException
("invokeAttr");
 			if ((namedParameters != null) && ((args == null)
|| args.Length < namedParameters.Length))
-				throw new ArgumentException
("namedParameters");
+				throw new ArgumentException
("namedParameters cannot be more than named arguments in number");
 
 			/* set some defaults if none are provided :-(
*/
 			if ((invokeAttr &
(BindingFlags.Public|BindingFlags.NonPublic)) == 0)
Index: class/corlib/System/TypeCode.cs
===================================================================
RCS file: /mono/mcs/class/corlib/System.Reflection/Binder.cs,v
retrieving revision 1.11
diff -u -r1.11 Binder.cs
--- class/corlib/System.Reflection/Binder.cs	11 May 2003 05:51:07
-0000	1.11
+++ class/corlib/System.Reflection/Binder.cs	28 Nov 2003 21:02:19
-0000
@@ -83,8 +83,14 @@
 							types [i] = args
[i].GetType ();
 					}
 				}
-				MethodBase selected = SelectMethod
(bindingAttr, match, types, modifiers);
+				
 				state = null;
+				MethodBase selected = null;
+				if(names == null)
+					selected = SelectMethod
(bindingAttr, match, types, modifiers);
+				else
+					selected = SelectMethod
(bindingAttr, match, ref args, modifiers, names);
+
 				return selected;
 			}
 

@@ -221,7 +234,214 @@
 					return to.IsAssignableFrom
(from);
 				}
 			}
+			
 
+			private static bool check_type (Type from, Type
to, out int matchVal) {
+				if (from == to){
+					matchVal = 1;
+					return true;
+				}
+				TypeCode fromt = Type.GetTypeCode
(from);
+				TypeCode tot = Type.GetTypeCode (to);
+				matchVal = -1;
+
+				switch (fromt) {
+				case TypeCode.Char:
+					switch (tot) {
+					case TypeCode.UInt16:
+						matchVal = 2;
+						return true;
+					case TypeCode.UInt32:
+						matchVal = 3;
+						return true;
+					case TypeCode.Int32:
+						matchVal = 4;
+						return true;
+					case TypeCode.UInt64:
+						matchVal = 5;
+						return true;
+					case TypeCode.Int64:
+						matchVal = 6;
+						return true;
+					case TypeCode.Single:
+						matchVal = 7;
+						return true;
+					case TypeCode.Double:
+						matchVal = 8;
+						return true;
+					}
+					matchVal = 50;
+					return to == typeof (object);
+				case TypeCode.Byte:
+					switch (tot) {
+					case TypeCode.Char:
+						matchVal = 2;
+						return true;
+					case TypeCode.UInt16:
+						matchVal = 3;
+						return true;
+					case TypeCode.Int16:
+						matchVal = 4;
+						return true;
+					case TypeCode.UInt32:
+						matchVal = 5;
+						return true;
+					case TypeCode.Int32:
+						matchVal = 6;
+						return true;
+					case TypeCode.UInt64:
+						matchVal = 7;
+						return true;
+					case TypeCode.Int64:
+						matchVal = 8;
+						return true;
+					case TypeCode.Single:
+						matchVal = 9;
+						return true;
+					case TypeCode.Double:
+						matchVal = 10;
+						return true;
+					}
+					matchVal = 50;
+					return to == typeof (object) ||
(from.IsEnum && to == typeof (Enum));
+				case TypeCode.SByte:
+					switch (tot) {
+					case TypeCode.Int16:
+						matchVal = 2;
+						return true;
+					case TypeCode.Int32:
+						matchVal = 3;
+						return true;
+					case TypeCode.Int64:
+						matchVal = 4;
+						return true;
+					case TypeCode.Single:
+						matchVal = 5;
+						return true;
+					case TypeCode.Double:
+						matchVal = 6;
+						return true;
+					}
+					matchVal = 50;
+					return to == typeof (object) ||
(from.IsEnum && to == typeof (Enum));
+				case TypeCode.UInt16:
+					switch (tot) {
+					case TypeCode.UInt32:
+						matchVal = 2;
+						return true;
+					case TypeCode.Int32:
+						matchVal = 3;
+						return true;
+					case TypeCode.UInt64:
+						matchVal = 4;
+						return true;
+					case TypeCode.Int64:
+						matchVal = 5;
+						return true;
+					case TypeCode.Single:
+						matchVal = 6;
+						return true;
+					case TypeCode.Double:
+						matchVal = 7;
+						return true;
+					}
+					matchVal = 50;
+					return to == typeof (object) ||
(from.IsEnum && to == typeof (Enum));
+				case TypeCode.Int16:
+					switch (tot) {
+					case TypeCode.Int32:
+						matchVal = 2;
+						return true;
+					case TypeCode.Int64:
+						matchVal = 3;
+						return true;
+					case TypeCode.Single:
+						matchVal = 4;
+						return true;
+					case TypeCode.Double:
+						matchVal = 5;
+						return true;
+					}
+					matchVal = 50;
+					return to == typeof (object) ||
(from.IsEnum && to == typeof (Enum));
+				case TypeCode.UInt32:
+					switch (tot) {
+					case TypeCode.UInt64:
+						matchVal = 2;
+						return true;
+					case TypeCode.Int64:
+						matchVal = 3;
+						return true;
+					case TypeCode.Single:
+						matchVal = 4;
+						return true;
+					case TypeCode.Double:
+						matchVal = 5;
+						return true;
+					}
+					matchVal = 50;
+					return to == typeof (object) ||
(from.IsEnum && to == typeof (Enum));
+				case TypeCode.Int32:
+					switch (tot) {
+					case TypeCode.Int64:
+						matchVal = 2;
+						return true;
+					case TypeCode.Single:
+						matchVal = 3;
+						return true;
+					case TypeCode.Double:
+						matchVal = 4;
+						return true;
+					}
+					matchVal = 50;
+					return to == typeof (object) ||
(from.IsEnum && to == typeof (Enum));
+				case TypeCode.UInt64:
+					switch (tot) {
+					case TypeCode.Int64:
+						matchVal = 2;
+						return true;
+					case TypeCode.Single:
+						matchVal = 3;
+						return true;
+					case TypeCode.Double:
+						matchVal = 4;
+						return true;
+					}
+					matchVal = 50;
+					return to == typeof (object) ||
(from.IsEnum && to == typeof (Enum));
+
+				case TypeCode.Int64:
+					switch (tot) {
+					case TypeCode.UInt64:
+						matchVal = 2;
+						return true;
+					case TypeCode.Single:
+						matchVal = 3;
+						return true;
+					case TypeCode.Double:
+						matchVal = 4;
+						return true;
+					}
+					matchVal = 50;
+					return to == typeof (object) ||
(from.IsEnum && to == typeof (Enum));
+				case TypeCode.Single:
+					if(tot ==  TypeCode.Double){
+						matchVal = 2;
+						return true;
+					}
+					matchVal = 50;
+					return to == typeof (object);
+				default:
+					/* TODO: handle valuetype ->
byref */
+					if (to == typeof (object) &&
from.IsValueType){
+						matchVal = 50;
+						return true;
+					}
+					
+					matchVal = 100;
+					return to.IsAssignableFrom
(from);
+				}
+			}
 			private static bool check_arguments (Type[]
types, ParameterInfo[] args) {
 				for (int i = 0; i < types.Length; ++i)
{
 					if (!check_type (types [i], args
[i].ParameterType))
@@ -229,6 +449,189 @@
 				}
 				return true;
 			}
+
+
+		private MethodBase SelectMethod (BindingFlags
bindingAttr,
+                        MethodBase[] match, ref object[] args,
ParameterModifier[] modifiers,
+                        string[] names)
+                {
+	                        int found = 0;
+	                        MethodBase m = null;
+	                        MethodBase tempM = null;
+				int matchVal = 0, totalMatchVal = 0,
utotalMatchVal = 0;
+				int selectedMethod = -1;
+				int NamedParamBestMatch = -1;
+				int UnnamedParamBestMatch = -1;
+				int [] matchSeq = new int
[names.Length];
+				int [] bestMatchSeq = new int
[names.Length];
+				int uNameParamLen = args.Length -
names.Length;
+				int [] ubestMatchSeq = null;
+				int [] umatchSeq = null;
+				if(uNameParamLen > 0){
+					ubestMatchSeq = new int
[uNameParamLen];
+					umatchSeq = new int
[uNameParamLen];
+				}
+				ParameterInfo[] param = null;
+
+				// go thru all the methods 
+                                for (int mi = 0; mi < match.Length;
++mi) {
+                                        m = match [mi];
+                                        param = m.GetParameters ();
+					// match the number of
prameters
+                                        if (args.Length !=
param.Length)
+                                                continue;
+					// for named parameters the
matching 
+					// param name is major criteria
+					// the name has to be matched
+					int j, k;
+					totalMatchVal = 0;
+					utotalMatchVal = 0;
+					found = 0;
+                                        for(j = 0; j<names.Length;
j++){
+                                                for(k = 0;
k<param.Length; k++){
+                                                       
if(param[k].Name == names[j])
+                                                               
break;
+						}
+						// if even one param
name doesn't match
+						// don't consider the
method
+                                                if(k >=
param.Length){
+							found = -1;
+                                                        break;
+						}
+                        
+						// if all the names
matches
+						// start checking types
for named 
+						// parameters
+						matchVal = 0;
+						if (check_type (args
[j].GetType (), param[k].ParameterType, out matchVal)){
+							matchSeq [j] =
matchVal;
+                                                	totalMatchVal =
totalMatchVal + matchVal;
+						}
+                                                else{
+							found = -1;
+                                                        break;
+						}
+                                        }
+
+					//if name or type desn't not
match pickup next method
+					if(found == -1)
+						continue;
+
+					// check if there are any
unnamed urguments
+					if(names.Length < args.Length){
+		                        	ParameterInfo[] parms =
param;
+	        	                	int currentPos =
names.Length;
+	        	                	for(int i=0, l=0;
i<parms.Length; i++){
+	        	                       	 	for(j = 0;
j<names.Length; j++){
+	        	                               
	if(parms[i].Name == names[j])
+	        	                                       
	break;
+							}
+							// chech types
for unnamed params
+	        	                        	if((j >=
names.Length) && (args.Length > currentPos)){
+
+							if(check_type
(args[currentPos].GetType(), parms[i].ParameterType, out matchVal)){
+									umatchSeq
[l++] = matchVal;
+	        	                                               
utotalMatchVal = utotalMatchVal + matchVal;
+	        	                                               
currentPos++;
+                	                        		}
+                	                        		else{
+									found
= -1;
+                	                               
		break;
+								}
+							}
+	        	                	}
+						
+					}
+					//if types not matched pickup
next method
+					if(found == -1)
+						continue;
+
+					// lower the value, better the
match
+					// hence we will keep only the
least totalMatchvalue 
+					// the preference goes to named
params
+					// first the named prams gets
chance to get the 
+					// better match then comes
unnamed params
+					if (NamedParamBestMatch >
totalMatchVal || NamedParamBestMatch == -1){
+						NamedParamBestMatch =
totalMatchVal;
+						UnnamedParamBestMatch =
utotalMatchVal;
+						for (int n = 0;
n<names.Length; n++)
+							bestMatchSeq [n]
= matchSeq [n];
+						if(uNameParamLen > 0){
+							for (int u = 0;
u<uNameParamLen; u++)
+								ubestMatchSeq
[u] = umatchSeq [u];
+						}
+						selectedMethod = mi;
+					}
+
+					// if two method returns the
same value for 
+					// then match types of each
param
+					// if all the types matches
return a 
+					// AmbiguousMatchException
+					else if (NamedParamBestMatch ==
totalMatchVal){
+						bool noMatch = false;
+						int n = 0;
+						if(uNameParamLen > 0) {
+							if(UnnamedParamBestMatch
== utotalMatchVal){
+								for(n =
0; n<uNameParamLen; n++){
+									if(ubestMatchSeq
[n] != umatchSeq [n]){
+										noMatch
= true;
+										break;
+									}
+								}
+							}
+							else
+								noMatch
= true;
+						}	
+						if(!noMatch){
+							for(n = 0;
n<names.Length; n++){
+								if(bestMatchSeq
[n] != matchSeq [n]){
+									noMatch
= true;
+									break;
+								}
+							}
+						}
+						if(!noMatch)
+							throw new
AmbiguousMatchException();
+					
+						if((uNameParamLen>0) &&
(UnnamedParamBestMatch > utotalMatchVal)){
+							UnnamedParamBestMatch
= utotalMatchVal;
+							for (n = 0;
n<names.Length; n++)
+								bestMatchSeq
[n] = matchSeq [n];
+							for (int u = 0;
u<uNameParamLen; u++)
+								ubestMatchSeq
[u] = umatchSeq [u];
+							selectedMethod =
mi;
+						}		
+					}
+					
+				}
+				// if no method matched
+				if(selectedMethod == -1)
+					return null;
+
+				param =
match[selectedMethod].GetParameters ();
+
+				// rearrange the argumets as per the 
+				// parameters of the qualified method
+				object[] tempArgs = new
object[args.Length];
+                        	int curPos = names.Length;
+				
+				for(int t = 0; t<param.Length; t++){
+					int j;
+	                       	 	for(j = 0; j<names.Length;
j++){
+	                                     	if(param[t].Name ==
names[j]){
+	                                               	tempArgs[t] =
args[j];
+	                                               	break;
+	                                       	}
+					}
+					if((j >= names.Length) &&
(args.Length > curPos)){
+		                                tempArgs[t] =
args[curPos];
+						curPos++;
+					}
+				}
+				args = tempArgs;
+	                        return match[selectedMethod];
+                	}
+		
 
 			public override MethodBase SelectMethod
(BindingFlags bindingAttr, MethodBase[] match, Type[] types,
ParameterModifier[] modifiers)
 			{




Index: class/corlib/Test/System/TypeTest.cs
===================================================================
RCS file: /mono/mcs/class/corlib/Test/System/TypeTest.cs,v
retrieving revision 1.1
diff -u -r1.1 TypeTest.cs
--- class/corlib/Test/System/TypeTest.cs	13 Jul 2003 14:29:25
-0000	1.1
+++ class/corlib/Test/System/TypeTest.cs	29 Nov 2003 11:37:56
-0000
@@ -8,8 +8,10 @@
 
 using NUnit.Framework;
 using System;
+using System.Reflection;
 using System.IO;
 
+
 namespace MonoTests.System
 {
 	class Super : ICloneable {
@@ -20,11 +22,15 @@
 	class Duper: Super {
 	}
 
+	
 	enum TheEnum { A, B, C };
 
 	[TestFixture]
 	public class TypeTest : Assertion
 	{
+		public static object [] values;
+		public static string methodId; 
+		
 		[Test]
 		public void TestIsAssignableFrom () {
 			// Simple tests for inheritance
@@ -77,6 +83,279 @@
 		public void TestIsSubclassOf () {
 			Assert (typeof (ICloneable).IsSubclassOf (typeof
(object)));
 		}
+
+		private void invokeMember(object [] argValues, string []
argNames) {
+			try {
+				values = new object[argValues.Length];
+			
+				Type t = typeof(TypeClass);
+				t.InvokeMember("checkMethod",
+					BindingFlags.InvokeMethod,
+					null,
+					null,
+					argValues, 
+					null, 
+					null,
+					argNames);
+			} catch (Exception e) {
+				throw (e);
+			}
+		}
+
+		[Test]
+		public void TestInvokeMember_Method () {
+			try{
+				object[] argValues = new object []
{"aaa", "bbb"};
+				string [] argNames = new string []
{"firstName", "lastName"};
+				invokeMember(argValues, argNames);
+				
+				AssertEquals("#A1", methodId, "m1");
+				AssertEquals("#A1",  argValues[0],
values[0]);
+				AssertEquals("#A1",  argValues[1],
values[1]);
+			}catch (Exception e){
+				Fail ("Unexpected exception at #A1 " +
e);
+			}
+
+			try{
+				object[] argValues = new object []
{"bbb", "aaa"};
+				string [] argNames = new string []
{"lastName", "firstName"};
+				invokeMember(argValues, argNames);
+				
+				AssertEquals("#A2", methodId, "m1");
+				AssertEquals("#A2",  argValues[0],
values[1]);
+				AssertEquals("#A2",  argValues[1],
values[0]);
+			}catch (Exception e){
+				Fail ("Unexpected exception at #A2 " +
e);
+			}
+
+			try{
+				object[] argValues = new object [] {12,
"bbb"};
+				string [] argNames = new string []
{"firstName", "lastName"};
+				invokeMember(argValues, argNames);
+			}catch (Exception e){
+				AssertEquals("#A3",
typeof(AmbiguousMatchException), e.GetType());
+			}
+
+			try{
+				object[] argValues = new object []
{"aaa", 12};
+				string [] argNames = new string []
{"firstName", "lastName"};
+				invokeMember(argValues, argNames);
+			}catch (Exception e){
+				AssertEquals("#A4",
typeof(MissingMethodException), e.GetType());
+			}
+
+			try{
+				object[] argValues = new object []
{"aaa", 12};
+				string [] argNames = new string []
{"firstName", 
+								"lastName",
"anotherName"};
+				invokeMember(argValues, argNames);
+			}catch (Exception e){
+				AssertEquals("#A5",
typeof(ArgumentException), e.GetType());
+			}
+
+			try{
+				double i = 10;
+				object[] argValues = new object []
{"aaa", "bbb", i};
+				string [] argNames = new string []
{"firstName", 
+									"lastName",
										"ID"};
+				invokeMember(argValues, argNames);
+				
+				AssertEquals("#A6", methodId, "m4");
+				AssertEquals("#A6",  argValues[0],
values[0]);
+				AssertEquals("#A6",  argValues[1],
values[1]);
+				AssertEquals("#A6",  argValues[2],
values[2]);
+			}catch (Exception e){
+				Fail ("Unexpected exception at #A6 " +
e);
+			}
+
+			try{
+				int i = 10;
+				object[] argValues = new object []
{"aaa", "bbb", i};
+				string [] argNames = new string []
{"firstName", 
+									"lastName",
										"ID"};
+				invokeMember(argValues, argNames);
+				
+				AssertEquals("#A7", methodId, "m5");
+				AssertEquals("#A7",  argValues[0],
values[0]);
+				AssertEquals("#A7",  argValues[1],
values[1]);
+				AssertEquals("#A7",  argValues[2],
values[2]);
+			}catch (Exception e){
+				Fail ("Unexpected exception at #A7 " +
e);
+			}
+
+			// unnamed parameters
+			try{
+				int i = 10;
+				object[] argValues = new object []
{"aaa", "bbb", i};
+				string [] argNames = new string []
{"firstName", "lastName"};
+				invokeMember(argValues, argNames);
+				
+				AssertEquals("#A8", methodId, "m5");
+				AssertEquals("#A8",  argValues[0],
values[0]);
+				AssertEquals("#A8",  argValues[1],
values[1]);
+				AssertEquals("#A8",  argValues[2],
values[2]);
+			}catch (Exception e){
+				Fail ("Unexpected exception at #A8 " +
e);
+			}
+
+			try{
+				Int16 i = 10;
+				object[] argValues = new object []
{"aaa", i, "zzz", 500};
+				string [] argNames = new string []
{"firstName", "ID"};
+				invokeMember(argValues, argNames);
+				
+				AssertEquals("#A9", methodId, "m7");
+				AssertEquals("#A9",  argValues[0],
values[0]);
+				AssertEquals("#A9",  argValues[1],
values[1]);
+				AssertEquals("#A9",  argValues[2],
values[2]);
+				AssertEquals("#A9",  argValues[3],
values[3]);
+			}catch (Exception e){
+				Fail ("Unexpected exception at #A9 " +
e);
+			}
+
+			try{
+				short s = 500;
+				Int64 i = 10;
+				object[] argValues = new object []
{"aaa", i, "zzz", s};
+				string [] argNames = new string []
{"firstName", "ID"};
+				invokeMember(argValues, argNames);
+				
+				AssertEquals("#A10", methodId, "m8");
+				AssertEquals("#A10",  argValues[0],
values[0]);
+				AssertEquals("#A10",  argValues[1],
values[1]);
+				AssertEquals("#A10",  argValues[2],
values[2]);
+				AssertEquals("#A10",  argValues[3],
values[3]);
+			}catch (Exception e){
+				Fail ("Unexpected exception at #A10 " +
e);
+			}
+			
+			try{
+				Int16 i = 10;
+				Int16 s = 500;
+				object[] argValues = new object []
{"aaa", i, "zzz", s};
+				string [] argNames = new string []
{"firstName", "ID"};
+				invokeMember(argValues, argNames);
+				
+				AssertEquals("#A11", methodId, "m7");
+				AssertEquals("#A11",  argValues[0],
values[0]);
+				AssertEquals("#A11",  argValues[1],
values[1]);
+				AssertEquals("#A11",  argValues[2],
values[2]);
+				AssertEquals("#A11",  argValues[3],
values[3]);
+			}catch (Exception e){
+				Fail ("Unexpected exception at #A11 " +
e);
+			}
+
+			try{
+				object[] argValues = new object []
{"aaa", 12, "bbb", "zzz", 20};
+				string [] argNames = new string []
{"firstName", "ID"};
+				invokeMember(argValues, argNames);
+			}catch (Exception e){
+				AssertEquals("#A12",
typeof(AmbiguousMatchException), e.GetType());
+			}
+
+			try{
+				object[] argValues = new object []
{"aaa", 12, "bbb", "zzz"};
+				string [] argNames = new string []
{"firstName", "ID"};
+				invokeMember(argValues, argNames);
+			}catch (Exception e){
+				AssertEquals("#A13",
typeof(MissingMethodException), e.GetType());
+			}
+			
+
+			try{
+				object[] argValues = new object []
{"aaa", 12, 20, "bbb"};
+				string [] argNames = new string []
{"firstName", "ID"};
+				invokeMember(argValues, argNames);
+			}catch (Exception e){
+				AssertEquals("#A14",
typeof(MissingMethodException), e.GetType());
+			}
+		}
 	}
+
+	public class TypeClass 
+	{
+		public static void checkMethod(string lastName, string
firstName)
+		{
+			TypeTest.methodId = "m1";
+			TypeTest.values[0] = firstName;
+			TypeTest.values[1] = lastName;
+		}
+
+		public static void checkMethod(string lastName, int
firstName)
+		{
+			TypeTest.methodId = "m2";
+		}
+
+		public static void checkMethod(int firstName, string
lastName)
+		{
+			TypeTest.methodId = "m3";
+		}
+
+		public static void checkMethod(string lastName, double
ID, string firstName)
+		{
+			TypeTest.methodId = "m4";
+			TypeTest.values[0] = firstName;
+			TypeTest.values[1] = lastName;
+			TypeTest.values[2] = ID;
+		}
+
+		public static void checkMethod(long ID, string lastName,
string firstName)
+		{
+			TypeTest.methodId = "m5";
+			TypeTest.values[0] = firstName;
+			TypeTest.values[1] = lastName;
+			TypeTest.values[2] = ID;
+		}
+		
+		public static void checkMethod(Int64 ID, string
lastName, string firstName,  Int64 sal)
+		{
+			TypeTest.methodId = "m6";
+			TypeTest.values[0] = firstName;
+			TypeTest.values[1] = ID;
+			TypeTest.values[2] = lastName;
+			TypeTest.values[3] = sal;
+		}
+
+		public static void checkMethod(Int32 ID, string
lastName, string firstName, int sal)
+		{
+			TypeTest.methodId = "m7";
+			TypeTest.values[0] = firstName;
+			TypeTest.values[1] = ID;
+			TypeTest.values[2] = lastName;
+			TypeTest.values[3] = sal;
+		}
+
+		public static void checkMethod(Int64 ID, string
lastName, Int32 sal, string firstName)
+		{
+			TypeTest.methodId = "m8";
+			TypeTest.values[0] = firstName;
+			TypeTest.values[1] = ID;
+			TypeTest.values[2] = lastName;
+			TypeTest.values[3] = sal;
+		}
+
+		public static void checkMethod(Int32 ID, string
lastName, string firstName, long sal)
+		{
+			TypeTest.methodId = "m9";
+			TypeTest.values[0] = firstName;
+			TypeTest.values[1] = ID;
+			TypeTest.values[2] = lastName;
+			TypeTest.values[3] = sal;
+		}
+
+
+		public static void checkMethod(Int32 ID, string val,
string lastName, string firstName, long sal)
+		{
+			TypeTest.methodId = "m9";
+		}
+
+		public static void checkMethod(Int32 ID, string val,
string lastName, long sal, string firstName)
+		{
+			TypeTest.methodId = "m9";
+		}
+
+
+	}
+
 }