Share via


Acceso a valores de argumento predeterminados

Algunos lenguajes (como Visual C++ y Microsoft Visual Basic 2005) admiten la asignación de valores predeterminados a argumentos. Por ejemplo, el ejemplo siguiente es una declaración legítima de Visual Basic 2005 con valores predeterminados para dos de los argumentos.

Public Sub MyMethod (a as Integer, _
                     Optional b as Double = 1.2, _
                     Optional c as Integer = 1)

Se puede utilizar un atributo de parámetro para asignar un valor de parámetro predeterminado.

En Visual Basic y C++, se pueden omitir los parámetros opcionales cuando se llama al método. En C#, se deben especificar valores para los argumentos opcionales.

Por ejemplo, todos los ejemplos siguientes son llamadas de Visual Basic y C++ válidas para 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

Para recuperar el valor predeterminado de un argumento mediante reflexión, hay que obtener un objeto ParameterInfo para el parámetro y, a continuación, recuperar el valor predeterminado mediante la propiedad ParameterInfo.DefaultValue. Si no hay ningún valor predeterminado, la propiedad devolverá Value.DBNull.

En el ejemplo siguiente, se muestran los valores predeterminados de MyMethod en la consola.

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);
}

Para invocar métodos que tienen argumentos con valores predeterminados, hay que utilizar Type.Missing como valor de parámetro en el método InvokeMember. De este modo, el servicio de enlace en tiempo de ejecución puede utilizar el valor predeterminado para el valor de parámetro indicado. Si se pasa Type.Missing para un parámetro sin valor predeterminado, se inicia una excepción ArgumentException. Es importante tener en cuenta que puede que no todos los mecanismos de enlace de los compiladores respeten estas reglas para Type.Missing. Algunos enlazadores podrían no admitir esta funcionalidad o podrían tratar Type.Missing de una manera diferente. Al utilizar Type.Missing, los valores predeterminados no tienen que ser finales.

El lenguaje C# no admite argumentos predeterminados.

El siguiente ejemplo de Visual Basic 2005 muestra cómo utilizar la reflexión para invocar métodos que tienen argumentos predeterminados.

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

Cuando se utiliza la técnica anterior, se toman en consideración los argumentos predeterminados finales incluso si el llamador no especifica ningún valor. Ésta es la manera más habitual de invocar métodos con argumentos predeterminados.

Si se utiliza MethodBase.Invoke para invocar el método, se deben especificar explícitamente los argumentos predeterminados pasando una matriz de objetos que contiene Type.Missing para todos los parámetros sin valores.

Vea también

Referencia

Type.Missing
Reflection.Missing
MethodBase.Invoke
InvokeMember

Conceptos

Ver información de tipos