访问默认参数值

某些语言(如 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 的对象数组。

请参见

参考

Type.Missing

Reflection.Missing

MethodBase.Invoke

InvokeMember

概念

查看类型信息