fix for sprnet-1107, sprnet-1111
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ;-)
|
||||
|
||||
Reference in New Issue
Block a user