Доступ к значениям аргументов по умолчанию
Некоторые языки (такие как Visual C++ и Microsoft Visual Basic 2005) поддерживают назначение аргументам значений по умолчанию. Например, ниже приведено допустимое объявление Visual Basic 2005, содержащее значения по умолчанию для двух аргументов.
Public Sub MyMethod (a as Integer, _
Optional b as Double = 1.2, _
Optional c as Integer = 1)
Для присвоения значения по умолчанию можно использовать атрибут параметра.
В Visual Basic и C++ дополнительные параметры могут быть пропущены при вызове метода. В C# значения дополнительных аргументов должны быть указаны.
Например, все эти примеры Visual Basic и C++ являются допустимыми вызовами MyMethod.
MyMethod(10, 55.3, 12)
MyMethod(10, 1.3) ' c == 1
MyMethod(11) ' b == 1.2, c == 1
MyMethod(10, 55.3, 12);
MyMethod(10, 1.3); // c == 1
MyMethod(11); // b == 1.2, c == 1
Чтобы получить значение по умолчанию аргумента при помощи отражения, получите объект ParameterInfo для этого параметра, затем получите значение по умолчанию с помощью свойства ParameterInfo.DefaultValue. Если отсутствует значение по умолчанию, свойство возвращает значение Value.DBNull.
В следующем примере на консоль выводятся значения по умолчанию для метода MyMethod.
Dim m As MethodInfo = t.GetMethod("MyMethod")
Dim ps As ParameterInfo() = m.GetParameters()
Dim i As Integer
For i = 0 To ps.Length - 1
Console.WriteLine("Default Value == {0}", ps(i).DefaultValue)
Next i
MethodInfo m = t.GetMethod("MyMethod");
ParameterInfo[] ps = m.GetParameters();
for (int i = 0; i < ps.Length; i++)
{
Console.WriteLine("Default Value == {0}", ps[i].DefaultValue);
}
MethodInfo m = t->GetMethod("MyMethod");
ParameterInfo[] ps = m->GetParameters();
for (int i = 0; i < ps.Length; i++)
{
Console::WriteLine(S"Default Value == {0}", ps[i]->DefaultValue);
}
Чтобы вызвать методы, имеющие аргументы со значениями по умолчанию, используйте Type.Missing в качестве значения параметра для метода InvokeMember. Это позволяет в ходе поздней привязки использовать значение по умолчанию для указанного значения параметра. Если Type.Missing передается для параметра, который не имеет значения по умолчанию, создается исключение ArgumentException. Важно отметить, что не все механизмы привязки в компиляторах могут следовать этим правилам для Type.Missing. Некоторые средства привязки могут не поддерживать эти функции или могут по-другому обрабатывать Type.Missing. Если используется поле Type.Missing, значения по умолчанию не обязательно должны быть последними.
Язык C# не поддерживает значения аргументов по умолчанию.
В следующем примере кода на языке Visual Basic 2005 показано, как используется отражение для вызова методов, в которых присутствуют аргументы по умолчанию.
Option Strict Off
Imports System
Imports System.Reflection
Public Class OptionalArg
Public Sub MyMethod (a As Integer, Optional b As Double = 1.2, Optional c As Integer=1)
Console.WriteLine("a = " & a & " b = " & b & " c = " & c)
End Sub
End Class
Module Module1
Sub Main()
Dim o As New OptionalArg
Dim t As Type
t = GetType(OptionalArg)
Dim Param As Object()= {10, 20, 30}
t.InvokeMember("MyMethod", _
BindingFlags.Public Or _
BindingFlags.Instance Or _
BindingFlags.InvokeMethod Or _
BindingFlags.OptionalParamBinding, _
Nothing, _
o, _
New Object() {10, 55.3, 12})
t.InvokeMember("MyMethod", _
BindingFlags.Public Or _
BindingFlags.Instance Or _
BindingFlags.InvokeMethod Or _
BindingFlags.OptionalParamBinding, _
Nothing, _
o, _
New Object() {10, 1.3, Type.Missing})
t.InvokeMember("MyMethod", _
BindingFlags.Public Or _
BindingFlags.Instance Or _
BindingFlags.InvokeMethod Or _
BindingFlags.OptionalParamBinding, _
Nothing, _
o, _
New Object() {10, Type.Missing, Type.Missing})
End Sub
End Module
При использовании такого способа последние аргументы, определяемые по умолчанию, принимаются во внимание даже в том случае, если в вызывающем коде не заданы значения. Это наиболее общий способ вызова методов с аргументами по умолчанию.
При вызове метода с помощью метода MethodBase.Invoke необходимо явным образом определить, какие аргументы принимаются по умолчанию; для этого передается массив объектов, содержащий значение Type.Missing для каждого параметра, значение которого не задано.