Métodos (Guía de programación de C#)

Un método es un bloque de código que contiene una serie de instrucciones.Los programas hacen que las instrucciones se ejecuten mediante una llamada al método y la especificación de los argumentos de método necesarios.En C#, cada instrucción se ejecuta en el contexto de un método.El método Main es el punto de entrada de cada aplicación C# al que llama Common Language Runtime (CLR) cuando se inicia el programa.

[!NOTA]

En este tema se analizan los métodos con nombre.Para obtener información sobre las funciones anónimas, vea Funciones anónimas (Guía de programación de C#).

Firmas de método

Los métodos se declaran en una clase o struct mediante la especificación del nivel de acceso como public o private, modificadores opcionales como abstract o sealed, el valor devuelto, el nombre del método y cualquier parámetro de método.Todos esos elementos constituyen la firma del método.

[!NOTA]

Un tipo de valor devuelto desde un método no forma parte de su firma a efectos de la sobrecarga de métodos.Sin embargo, sí forma parte de la firma del método a la hora de determinar la compatibilidad entre un delegado y el método al que apunta.

Los parámetros del método se encierran entre paréntesis y se separan por comas.Los paréntesis vacíos indican que el método no requiere ningún parámetro.Esta clase contiene tres métodos:

abstract class Motorcycle
{
    // Anyone can call this.
    public void StartEngine() {/* Method statements here */ }

    // Only derived classes can call this.
    protected void AddGas(int gallons) { /* Method statements here */ }

    // Derived classes can override the base class implementation.
    public virtual int Drive(int miles, int speed) { /* Method statements here */ return 1; }

    // Derived classes must implement this.
    public abstract double GetTopSpeed(); 
}

Acceso al método

Llamar a un método de un objeto es como obtener acceso a un campo.Después del nombre de objeto, agregue un punto, el nombre del método y paréntesis.Los argumentos se colocan entre paréntesis y separados por comas.Por tanto, se puede llamar a los métodos de la clase Motorcycle como en el ejemplo siguiente:

class TestMotorcycle : Motorcycle
{

    public override double GetTopSpeed()
    {
        return 108.4;
    }

    static void Main()
    {

        TestMotorcycle moto = new TestMotorcycle();

        moto.StartEngine();
        moto.AddGas(15);
        moto.Drive(5, 20);
        double speed = moto.GetTopSpeed();
        Console.WriteLine("My top speed is {0}", speed);            
    }
}

Parámetros de método VS. argumentos

La definición de método especifica los nombres y tipos de cualquier parámetro que se requiera.Cuando el código de llamada llama al método, proporciona valores concretos denominados argumentos a cada parámetro.Los argumentos deben ser compatibles con el tipo de parámetro pero el nombre del argumento (si existe) que se usa en el código de llamada no tiene que ser igual que el nombre de parámetro definido en el método.Por ejemplo:

public void Caller()
{
    int numA = 4;
    // Call with an int variable.
    int productA = Square(numA);

    int numB = 32;
    // Call with another int variable.
    int productB = Square(numB);

    // Call with an integer literal.
    int productC = Square(12);

    // Call with an expression that evaulates to int.
    productC = Square(productA * 3);
}

int Square(int i)
{
    // Store input argument in a local variable.
    int input = i;
    return input * input;
}

Al pasar por referencia VS. pasar por valor

De forma predeterminada, cuando un tipo de valor se pasa a un método, se pasa una copia en lugar del propio objeto.Por tanto, los cambios en el argumento no tienen ningún efecto en la copia original del método de llamada.Puede pasar un tipo de valor por referencia mediante la palabra clave ref.Para obtener más información, vea Pasar parámetros de tipo de valor (Guía de programación de C#).Para obtener una lista de los tipos de valor integrados, vea Tabla de tipos de valor (Referencia de C#).

Cuando un objeto de un tipo de referencia se pasa a un método, una referencia al objeto se pasa.Es decir, el método recibe no el propio objeto pero un argumento que indica la ubicación del objeto.Si cambia un miembro del objeto con esta referencia, el cambio se refleja en el argumento en el método de llamada, incluso si se pasa el objeto por valor.

Cree un tipo de referencia mediante la palabra clave class , como se muestra en el ejemplo siguiente.

public class SampleRefType
{
    public int value;
}

Ahora, si se pasa un objeto basado en este tipo a un método, una referencia al objeto se pasa.El ejemplo siguiente se pasa un objeto SampleRefType escrito en el método ModifyObject.

public static void TestRefType()
{
    SampleRefType rt = new SampleRefType();
    rt.value = 44;
    ModifyObject(rt);
    Console.WriteLine(rt.value);
}
static void ModifyObject(SampleRefType obj)
{
    obj.value = 33;
}

El ejemplo hace esencialmente la misma acción que el ejemplo anterior en que pasa un argumento por valor a un método.Pero, porque se utiliza un tipo de referencia, el resultado es diferente.La modificación que se crea en ModifyObject al campo value de parámetro, obj, también cambia el campo value argument, rt, en el método TestRefType .El método TestRefType muestra 33 como salida.

Para obtener más información sobre cómo pasar tipos de referencia por referencia y por valor, vea Pasar parámetros Reference-Type (Guía de programación de C#) y Tipos de referencia (Referencia de C#).

Valores devueltos

Los métodos pueden devolver un valor al llamador.Si el tipo de valor devuelto (el que aparece antes del nombre del método) no es void, el método puede devolver el valor mediante la palabra clave return.Una instrucción con la palabra clave return seguida de un valor que se corresponda con el tipo de valor devuelto devolverá ese valor al llamador del método.La palabra clave return también detiene la ejecución del método.Si el tipo de valor devuelto es void, una instrucción return sin ningún valor sigue siendo útil para detener la ejecución del método.Sin la palabra clave return, el método detendrá la ejecución cuando llegue al fin del bloque de código.Es necesario que los métodos con un tipo de valor devuelto no nulo utilicen la palabra clave return para devolver un valor.Por ejemplo, estos dos métodos utilizan la palabra clave return para devolver enteros:

class SimpleMath
{
    public int AddTwoNumbers(int number1, int number2)
    {
        return number1 + number2;
    }

    public int SquareANumber(int number)
    {
        return number * number;
    }
}

Para emplear un valor devuelto desde un método, el método que realiza la llamada puede utilizar la propia llamada al otro método en cualquier parte donde pueda aparecer un valor del mismo tipo.El valor devuelto también se puede asignar a una variable.Por ejemplo, los dos ejemplos de código siguientes logran el mismo objetivo:

int result = obj.AddTwoNumbers(1, 2);
result = obj.SquareANumber(result);
// The result is 9.
Console.WriteLine(result);
result = obj.SquareANumber(obj.AddTwoNumbers(1, 2));
// The result is 9.
Console.WriteLine(result);

Mediante una variable local, en este caso, result, almacenar un valor es opcional.Puede ayudar a la legibilidad del código o puede ser necesaria si necesita almacenar el valor original del argumento para todo el ámbito del método.

Para obtener más información, vea return (Referencia de C#).

Métodos Async

Utilizando la característica de async, puede invocar métodos asincrónicos sin usar devoluciones explícitos o manualmente dividir el código a través de varios métodos o de expresiones lambda.La característica async era Visual Studio 2012introducido.

Si marca un método con el modificador async , puede utilizar el operador espera en el método.Cuando el control alcanza una expresión de aguardar en el método async, el control vuelve al llamador, y el progreso en el método se suspende hasta que la tarea aguardada complete.Cuando finaliza la tarea, la ejecución se puede reanudar en el método.

[!NOTA]

Un método async vuelve al llamador cuando cualquiera que encuentra el primer objeto aguardado que aún no se completa o obtiene al final del método async, lo que ocurre primero.

Un método async puede tener un tipo de valor devuelto Task<TResult>, Task, o void.Se usa el tipo de valor devuelto void principalmente para definir controladores de eventos, donde se requiere un tipo de valor devuelto void.Un método async que devuelve void no se puede aguardar, y el llamador de un método vacío- que devuelve no puede detectar las excepciones que el método produce.

En el ejemplo siguiente, DelayAsync es un método async que tiene un tipo de valor devuelto Task<TResult>.DelayAsync tiene una instrucción return que devuelva un entero.Por consiguiente la declaración de método DelayAsync debe tener un tipo de valor devuelto Task<int>.Dado que el tipo de valor devuelto es Task<int>, la evaluación de la expresión await en DoSomethingAsync genera un entero mientras la instrucción siguiente muestra: int result = await delayTask.

El método startButton_Click es un ejemplo de un método async que tenga un tipo de valor devuelto void.Dado que DoSomethingAsync es un método async, la tarea para la llamada a DoSomethingAsync debe ser aguardada, como la instrucción siguiente muestra: await DoSomethingAsync();.El método startButton_Click debe definirse con el modificador async porque el método tiene una expresión await .

// using System.Diagnostics;
// using System.Threading.Tasks;

// This Click event is marked with the async modifier.
private async void startButton_Click(object sender, RoutedEventArgs e)
{
    await DoSomethingAsync();
}

private async Task DoSomethingAsync()
{
    Task<int> delayTask = DelayAsync();
    int result = await delayTask;

    // The previous two statements may be combined into
    // the following statement.
    //int result = await DelayAsync();

    Debug.WriteLine("Result: " + result);
}

private async Task<int> DelayAsync()
{
    await Task.Delay(100);
    return 5;
}

// Output:
//  Result: 5

Un método async no puede declarar los parámetros referencia o out , pero puede llamar a los métodos que tienen estos parámetros.

Para obtener más información sobre los métodos async, vea Programación asincrónica con Async y Await (C# y Visual Basic), Flujo de control en programas asincrónicos (C# y Visual Basic), y Tipos de valor devuelto de Async (C y Visual Basic).

Iteradores

Un iterador realiza una iteración personalizada en una colección, como una lista o matriz.Un iterador utiliza la instrucción retorno de producción para devolver cada elemento de uno en uno.Cuando se alcanza una instrucción retorno de producción , la ubicación actual en el código se recuerda.La ejecución se reinicia desde esa ubicación cuando el iterador se denomina la próxima vez.

Se llama a un iterador de código de cliente mediante una instrucción foreach .

El tipo de un iterador puede ser IEnumerable, IEnumerable<T>, IEnumerator, o IEnumerator<T>.

Para obtener más información, vea Iteradores (C# y Visual Basic).

Especificación del lenguaje C#

Para obtener más información, vea la Especificación del lenguaje C#. La especificación del lenguaje es la fuente definitiva de la sintaxis y el uso de C#.

Vea también

Referencia

Clases y structs (Guía de programación de C#)

Modificadores de acceso (Guía de programación de C#)

Clases estáticas y sus miembros (Guía de programación de C#)

Herencia (Guía de programación de C#)

Clases y miembros de clase abstractos y sellados (Guía de programación de C#)

params (Referencia de C#)

return (Referencia de C#)

out (Referencia de C#)

ref (Referencia de C#)

Pasar parámetros (Guía de programación de C#)

Conceptos

Guía de programación de C#