Determining type compatiblity
-
Hi folks! I've coded myself into another corner... again! I need a guru. This time, I'm writing code that checks that the parameter list for a call to a method is valid. Why? Because I am dynamically calling various methods with parameters read from an XML file. Why? Don't ask... looooong story. Breifly, a call to my routine might look like
StandardTest.PerformDALvsDBTest(
"DALRoutines", // the class that will contain the method to call
"InsertCustomer", // the method to be called
new object[] {
DateTime.Parse(parm0),
parm1,
Int32.Parse(parm2)
}
);Okay. So my routine goes through a bunch of checks and finally obtains a reference to the method to be called (
MethodInfo.methodRef
). The call to the method will be made usingmethodRef.Invoke(null, myBindings, null, Params, null);
But first, I must make sure that all the items in the
object[] Params
are of the right type. To do that I loop throughmethodRef.GetParameters()
and check each one against eachParams[index].GetType()
. If there are the correct number of parameters, and they are all of the correct type, etc, then I will perform theInvoke()
, otherwise, I throw an error indicating the method name, the parameter, the expected type and the type that was used: e.g. "The System.Type for parameter #0 in the parameter list for the method [DALRoutines.InsertCustomer] is System.DateTime; System.TimeSpan was expected". So, here is my problem: I have a method that expects a parameter to be anInt32
. However, when the value is passed in theobject[] Params
, it seems to be changed toInt16
(even if I specifically indicate that it isInt32
as above - I assume that it is because it is a small value). When my routine starts comparing parameter types it spits out an error saying it was passed anInt16
when it expects anInt32
. The kicker is that the call toInvoke()
would still work if it was made - .NET does not seem to mind and handles the conversion inherently. But I can't find a way to tell that it would work - all I can see is that the two types are different. I have tried investigating different ways to tell if the types are compatible (includingType.IsSubclassOf()
andType.IsAssignableFrom()
) but I can't seem to find anything that will let me know that anInt16
can be used as the val -
Hi folks! I've coded myself into another corner... again! I need a guru. This time, I'm writing code that checks that the parameter list for a call to a method is valid. Why? Because I am dynamically calling various methods with parameters read from an XML file. Why? Don't ask... looooong story. Breifly, a call to my routine might look like
StandardTest.PerformDALvsDBTest(
"DALRoutines", // the class that will contain the method to call
"InsertCustomer", // the method to be called
new object[] {
DateTime.Parse(parm0),
parm1,
Int32.Parse(parm2)
}
);Okay. So my routine goes through a bunch of checks and finally obtains a reference to the method to be called (
MethodInfo.methodRef
). The call to the method will be made usingmethodRef.Invoke(null, myBindings, null, Params, null);
But first, I must make sure that all the items in the
object[] Params
are of the right type. To do that I loop throughmethodRef.GetParameters()
and check each one against eachParams[index].GetType()
. If there are the correct number of parameters, and they are all of the correct type, etc, then I will perform theInvoke()
, otherwise, I throw an error indicating the method name, the parameter, the expected type and the type that was used: e.g. "The System.Type for parameter #0 in the parameter list for the method [DALRoutines.InsertCustomer] is System.DateTime; System.TimeSpan was expected". So, here is my problem: I have a method that expects a parameter to be anInt32
. However, when the value is passed in theobject[] Params
, it seems to be changed toInt16
(even if I specifically indicate that it isInt32
as above - I assume that it is because it is a small value). When my routine starts comparing parameter types it spits out an error saying it was passed anInt16
when it expects anInt32
. The kicker is that the call toInvoke()
would still work if it was made - .NET does not seem to mind and handles the conversion inherently. But I can't find a way to tell that it would work - all I can see is that the two types are different. I have tried investigating different ways to tell if the types are compatible (includingType.IsSubclassOf()
andType.IsAssignableFrom()
) but I can't seem to find anything that will let me know that anInt16
can be used as the valYou could always try to perform a cast on it. It's not the most efficient method, but I figure that's not what you're worried about - what with the reflection and all.
Deja View - the feeling that you've seen this post before.
-
Hi folks! I've coded myself into another corner... again! I need a guru. This time, I'm writing code that checks that the parameter list for a call to a method is valid. Why? Because I am dynamically calling various methods with parameters read from an XML file. Why? Don't ask... looooong story. Breifly, a call to my routine might look like
StandardTest.PerformDALvsDBTest(
"DALRoutines", // the class that will contain the method to call
"InsertCustomer", // the method to be called
new object[] {
DateTime.Parse(parm0),
parm1,
Int32.Parse(parm2)
}
);Okay. So my routine goes through a bunch of checks and finally obtains a reference to the method to be called (
MethodInfo.methodRef
). The call to the method will be made usingmethodRef.Invoke(null, myBindings, null, Params, null);
But first, I must make sure that all the items in the
object[] Params
are of the right type. To do that I loop throughmethodRef.GetParameters()
and check each one against eachParams[index].GetType()
. If there are the correct number of parameters, and they are all of the correct type, etc, then I will perform theInvoke()
, otherwise, I throw an error indicating the method name, the parameter, the expected type and the type that was used: e.g. "The System.Type for parameter #0 in the parameter list for the method [DALRoutines.InsertCustomer] is System.DateTime; System.TimeSpan was expected". So, here is my problem: I have a method that expects a parameter to be anInt32
. However, when the value is passed in theobject[] Params
, it seems to be changed toInt16
(even if I specifically indicate that it isInt32
as above - I assume that it is because it is a small value). When my routine starts comparing parameter types it spits out an error saying it was passed anInt16
when it expects anInt32
. The kicker is that the call toInvoke()
would still work if it was made - .NET does not seem to mind and handles the conversion inherently. But I can't find a way to tell that it would work - all I can see is that the two types are different. I have tried investigating different ways to tell if the types are compatible (includingType.IsSubclassOf()
andType.IsAssignableFrom()
) but I can't seem to find anything that will let me know that anInt16
can be used as the val -
Would something like this be okay?
public static bool ImplicitCastAllowed(Type type, object value) { try { Convert.ChangeType(value, type); return true; } catch { return false; } }
regards
Thanks guys - but I found the cause of the problem... P.E.B.K.A.C.! I was actually rewriting the routine to use
Convert()
(thanks Greeeg), when I noticed that I my error message was printing out the wrong info - instead of saying that the parm was "of type passedParmType; requiredParmType was expected", it said it was of "type requiredParmType; passedParmType was expected"! That led to finding other places where I had mixed up the two references (due to an ambiguous naming convention). Once I fixed that I found that my code was actually working correctly and warning me that I was trying to use anInt32
as a value to anInt16
parameter. :doh: Perhaps I should consider a change of career. I hear that Air Traffic Control is less stressful... and apparently the FAA is much more lenient about minor errors than IT managers.Clive Pottinger Victoria, BC