see remarks para example cref comment c# function parameters out

para - remarks c#



¿C#soporta los parámetros de entrada? (4)

En C #, estoy usando un StreamReader para leer un archivo, línea por línea. También mantengo el número de la línea actual en un int , para informes de posibles mensajes de error.

La lectura de cada línea va junto con algunas pruebas (por ejemplo, las líneas que comienzan con # son comentarios y deben omitirse), por lo que estoy planeando colocar todo el procedimiento de lectura en una función, que seguirá leyendo hasta que encuentre una línea útil , y luego devuelve esa línea. Si encuentra EOF , simplemente devolverá null .

Pensé que estaba siendo inteligente cuando string read(StreamReader sr, out int lineNumber) esta función como string read(StreamReader sr, out int lineNumber) , pero ahora resulta que C # no podrá hacer algo como lineNumber++ dentro de esa función. Se supone que la variable aún no se ha asignado, probablemente porque no tiene forma de saber si se ha asignado antes de esta llamada de función.

Entonces, el problema es simple: ¿cómo puedo especificar que esta variable es un parámetro de entrada (creo que ese es el término; lo he oído mencionar en el contexto de otros lenguajes de programación)? ¿Es esto posible en primer lugar? Absolutamente no voy a hacer que lineNumber miembro de mi clase , por lo que no es una opción.


Como todos dicen, simplemente puedes usar ref .

Voy a sugerir un enfoque alternativo, solo para que ustedes estén conscientes de ello.

Podría escribir un método que devolviera una IEnumerable<Line> donde Line es una clase muy simple que simplemente encapsula una línea de texto y un número de línea:

public class Line { public string Text; public int Number; }

Entonces tu método para leer las líneas podría verse algo así:

public IEnumerable<Line> ReadLines(StreamReader sr) { int number = 0; while (true) { string line = sr.ReadLine(); if (line == null) break; ++number; if (wantLine(line)) // Some predicate which decides if you want to keep the line. yield return new Line{Text = line, Number = number}; } }

Entonces podrías usarlo de la siguiente manera:

public void Test() { StreamReader sr = new StreamReader("Whatever"); foreach (var line in ReadLines(sr)) { if (line.Text == "SomeSpecialValue") doSomethingWith(line.Text, line.Number); } }

Esto es más trabajo para escribir, pero creo que puede resultar en un código más claro, y también tiene la ventaja de que el contador del número de línea está completamente oculto dentro de ReadLines() . (No es un miembro de su clase en el sentido de que es un campo en su clase; es solo una variable local en el método).


En ese caso, necesita un parámetro de ref lugar de out . Con la palabra clave out la responsabilidad de asignar / crear una instancia de un valor está dentro del método llamado de llamada; con ref está fuera del método que se llama.

Ver también: cuándo usar ref vs out


Un ref es lo que necesitas

MSDN

La palabra clave de parámetro de método ref en un parámetro de método hace que un método se refiera a la misma variable que se pasó al método. Cualquier cambio realizado en el parámetro en el método se reflejará en esa variable cuando el control vuelva al método de llamada.


Use la palabra clave ref en lugar de salir. Esto obligará a la persona que llama a iniciar el argumento antes de llamar.

Desde la MSDN - ref (C #)

Un argumento pasado a un parámetro ref debe primero ser inicializado. Compare esto con un parámetro de salida, cuyo argumento no tiene que inicializarse explícitamente antes de pasarlo a un parámetro de salida.