Invoke method with [Optional] with default value through Reflection
Is it possible to through reflection to invoke a method with an
[Optional]
attribute. For example Type.Missing
works for an argument with a default value but not for an [Optional]
argument.
using System;
using System.Reflection;
using System.Runtime.InteropServices;
public class Program
{
public static void Main(string[] args)
{
object? test1 = typeof(Program).GetMethod("MethodWithDefault").Invoke(null, new[] { Type.Missing });
object? test2 = typeof(Program).GetMethod("MethodWithOptional").Invoke(null, new[] { Type.Missing });
Console.WriteLine(test1);
Console.WriteLine(test2);
}
public static int MethodWithDefault(int value = 1) => value;
public static int MethodWithOptional([Optional]int value) => value;
}
using System;
using System.Reflection;
using System.Runtime.InteropServices;
public class Program
{
public static void Main(string[] args)
{
object? test1 = typeof(Program).GetMethod("MethodWithDefault").Invoke(null, new[] { Type.Missing });
object? test2 = typeof(Program).GetMethod("MethodWithOptional").Invoke(null, new[] { Type.Missing });
Console.WriteLine(test1);
Console.WriteLine(test2);
}
public static int MethodWithDefault(int value = 1) => value;
public static int MethodWithOptional([Optional]int value) => value;
}
1 Reply
I'm assuming I'll have to get the
I realised I never shared the error when trying to use
It does work for
ParameterInfo
for the argument, check if IsOptional
and use DefaultValue
to get the default value to pass in rather than Type.Missing
Hmm no that won't work as the DefaultValue
is Type.Missing
when no explicit default value is set
Add-Type -TypeDefinition @'
using System;
using System.Runtime.InteropServices;
public class MyClass
{
public static int TestMethod1(int value = 1) => value;
public static int TestMethod2([Optional] int value) => value;
public static int TestMethod3([Optional, DefaultParameterValue(1)] int value) => value;
}
'@
[MyClass].GetMethod('TestMethod1').GetParameters()
ParameterType : System.Int32
Name : value
HasDefaultValue : True
DefaultValue : 1
RawDefaultValue : 1
MetadataToken : 134217729
Attributes : Optional, HasDefault
Member : Int32 TestMethod1(Int32)
Position : 0
IsIn : False
IsLcid : False
IsOptional : True
IsOut : False
IsRetval : False
CustomAttributes : {[System.Runtime.InteropServices.OptionalAttribute()]}
[MyClass].GetMethod('TestMethod2').GetParameters()
ParameterType : System.Int32
Name : value
HasDefaultValue : False
DefaultValue : System.Reflection.Missing
RawDefaultValue : System.Reflection.Missing
MetadataToken : 134217730
Attributes : Optional
Member : Int32 TestMethod2(Int32)
Position : 0
IsIn : False
IsLcid : False
IsOptional : True
IsOut : False
IsRetval : False
CustomAttributes : {[System.Runtime.InteropServices.OptionalAttribute()]}
[MyClass].GetMethod('TestMethod3').GetParameters()
ParameterType : System.Int32
Name : value
HasDefaultValue : True
DefaultValue : 1
RawDefaultValue : 1
MetadataToken : 134217731
Attributes : Optional, HasDefault
Member : Int32 TestMethod3(Int32)
Position : 0
IsIn : False
IsLcid : False
IsOptional : True
IsOut : False
IsRetval : False
CustomAttributes : {[System.Runtime.InteropServices.OptionalAttribute()]}
Add-Type -TypeDefinition @'
using System;
using System.Runtime.InteropServices;
public class MyClass
{
public static int TestMethod1(int value = 1) => value;
public static int TestMethod2([Optional] int value) => value;
public static int TestMethod3([Optional, DefaultParameterValue(1)] int value) => value;
}
'@
[MyClass].GetMethod('TestMethod1').GetParameters()
ParameterType : System.Int32
Name : value
HasDefaultValue : True
DefaultValue : 1
RawDefaultValue : 1
MetadataToken : 134217729
Attributes : Optional, HasDefault
Member : Int32 TestMethod1(Int32)
Position : 0
IsIn : False
IsLcid : False
IsOptional : True
IsOut : False
IsRetval : False
CustomAttributes : {[System.Runtime.InteropServices.OptionalAttribute()]}
[MyClass].GetMethod('TestMethod2').GetParameters()
ParameterType : System.Int32
Name : value
HasDefaultValue : False
DefaultValue : System.Reflection.Missing
RawDefaultValue : System.Reflection.Missing
MetadataToken : 134217730
Attributes : Optional
Member : Int32 TestMethod2(Int32)
Position : 0
IsIn : False
IsLcid : False
IsOptional : True
IsOut : False
IsRetval : False
CustomAttributes : {[System.Runtime.InteropServices.OptionalAttribute()]}
[MyClass].GetMethod('TestMethod3').GetParameters()
ParameterType : System.Int32
Name : value
HasDefaultValue : True
DefaultValue : 1
RawDefaultValue : 1
MetadataToken : 134217731
Attributes : Optional, HasDefault
Member : Int32 TestMethod3(Int32)
Position : 0
IsIn : False
IsLcid : False
IsOptional : True
IsOut : False
IsRetval : False
CustomAttributes : {[System.Runtime.InteropServices.OptionalAttribute()]}
Invoke(null, new[] { Type.Missing });
for TestMethod2
, it is
Object of type 'System.Reflection.Missing' cannot be converted to type 'System.Int32'.
Object of type 'System.Reflection.Missing' cannot be converted to type 'System.Int32'.
TestMethod1
and TestMethod3
though
Opened https://github.com/dotnet/runtime/issues/100322