fix for sprnet-1107, sprnet-1111

This commit is contained in:
eeichinger
2008-11-21 01:51:07 +00:00
parent 0aabd9d9c8
commit fc72a56b3f
4 changed files with 87 additions and 5 deletions

View File

@@ -101,6 +101,7 @@ namespace Spring.Reflection.Dynamic
#endregion
private readonly FunctionDelegate method;
private readonly object[] nullArguments;
/// <summary>
/// Creates a new instance of the safe method wrapper.
@@ -112,6 +113,7 @@ namespace Spring.Reflection.Dynamic
this.methodInfo = methodInfo;
this.method = GetOrCreateDynamicMethod(methodInfo);
this.nullArguments = new object[methodInfo.GetParameters().Length];
}
/// <summary>
@@ -126,8 +128,15 @@ namespace Spring.Reflection.Dynamic
/// <returns>
/// A method return value.
/// </returns>
public object Invoke(object target, object[] arguments)
public object Invoke(object target, params object[] arguments)
{
// special case - when calling Invoke(null,null) it is undecidible if the second null is an argument or the argument array
if (arguments==null && nullArguments.Length==1) arguments=nullArguments;
AssertUtils.IsTrue(
nullArguments.Length == (arguments==null?0:arguments.Length)
, string.Format("Invalid number of arguments passed into method {0} - expected {1}, but was {2}", methodInfo.Name, nullArguments.Length, arguments.Length)
);
return this.method(target, arguments);
}
#else

View File

@@ -698,14 +698,22 @@ namespace Spring.Reflection.Dynamic
/// </remarks>
public static object ConvertValueTypeArgumentIfNecessary( object value, Type targetType, int argIndex )
{
// targetType is guaranteed to be a ValueType!
if (value == null)
{
if (ReflectionUtils.IsNullableType(targetType))
{
return null;
}
throw new InvalidCastException( string.Format( "Cannot convert NULL at position {0} to argument type {1}", argIndex, targetType.FullName ) );
}
Type valueType = value.GetType();
#if NET_2_0
if (ReflectionUtils.IsNullableType( targetType ))
{
targetType = Nullable.GetUnderlyingType(targetType);
}
#endif
// no conversion necessary?
if (valueType == targetType)
{

View File

@@ -54,7 +54,19 @@ namespace Spring.Util
public const BindingFlags AllMembersCaseInsensitiveFlags = BindingFlags.Public |
BindingFlags.NonPublic | BindingFlags.Instance
| BindingFlags.Static
| BindingFlags.IgnoreCase;
| BindingFlags.IgnoreCase;
/// <summary>
/// Checks, if the specified type is a nullable
/// </summary>
public static bool IsNullableType( Type type )
{
#if NET_2_0
return (type.IsGenericType && type.GetGenericTypeDefinition()==typeof(Nullable<>));
#else
return false;
#endif
}
/// <summary>
/// Returns signature for the specified <see cref="System.Type"/>, method name and argument

View File

@@ -108,6 +108,37 @@ namespace Spring.Reflection.Dynamic
Assert.IsFalse((bool) isNullOrEmpty.Invoke(null, new object[] { "Ana Maria" }));
}
#if NET_2_0
[Test]
public void PassNullableArguments()
{
IDynamicMethod dm = DynamicMethod.Create(typeof(TestMethods).GetMethod("PassNullableArgumentStatic"));
DateTime dt = DateTime.Now;
Assert.AreEqual(dt, dm.Invoke(null, dt));
}
#endif
[Test]
public void PassInvalidNumberOfArguments()
{
IDynamicMethod dm = DynamicMethod.Create(typeof(TestMethods).GetMethod("PassNullableArgumentStatic"));
DateTime dt = DateTime.Now;
Assert.IsNull(dm.Invoke(null, null)); // this is ok
try
{
dm.Invoke( null ); // this is not ok
Assert.Fail();
}
catch (ArgumentException) { }
try
{
dm.Invoke( null, null, null ); // this is not ok
Assert.Fail();
}
catch (ArgumentException) { }
}
[Test]
public void TestArgumentTypeCasts()
{
@@ -225,7 +256,29 @@ namespace Spring.Reflection.Dynamic
}
#endregion
#region Helper Classes
#if NET_2_0
class TestMethods
{
public static object Invoke( object target, object[] args )
{
return PassNullableArgumentStatic( (DateTime?)(args[0]) );
}
public DateTime? PassNullableArgument( DateTime? arg )
{
return PassNullableArgumentStatic( arg );
}
public static DateTime? PassNullableArgumentStatic( DateTime? arg )
{
return arg;
}
}
#endif
#endregion
}
#region IL generation helper classes (they help if you look at them in Reflector ;-)