es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

`CallerArgumentExpression` siempre es nulo (C# 10)

Estoy tratando de usar el atributo CallerArgumentExpression, junto con la sugerencia para validar registros encontrada aquí, pero la expresión siempre es nula. Estoy haciendo esto en una aplicación de consola .NET6 Core. El mismo código exacto funciona bien en LinqPad 7 (.NET6).

Tengo una clase base record que contiene métodos de validación comunes (casi copiados de esa otra respuesta)…

“`c#
public record CommonValidation {
internal static bool NonEmptyOrNullString(string s, [CallerArgumentExpression("s")] string expr = default) {
if (string.IsNullOrWhiteSpace(s)) {
throw new ArgumentException($"{expr} no puede ser nulo o vacío");
}
return true;
}

<pre><code>internal static bool NonZeroInt(int n, [CallerArgumentExpression("n")] string expr = default) {
if (n < 0) {
throw new ArgumentException($"{expr} no puede ser negativo");
}
return true;
}
</code></pre>

}

<pre><code><br />Luego puedo crear un <code>record</code> de la siguiente manera…

“`c#
public record Address(string Street, string City, string State, string Country, string Postcode) : CommonValidation {
private bool _ = NonEmptyOrNullString(Street)
&& NonEmptyOrNullString(City)
&& NonEmptyOrNullString(State)
&& NonEmptyOrNullString(Country)
&& NonEmptyOrNullString(Postcode);
}

Si intento crear una Address con un State vacío…

c#
Address a = new("5 My Street", "Somewhere", "", "Oz", "12345");

…se lanzará la excepción, pero la variable expr es nula. Como dije, el mismo código exacto funciona bien en LinqPad, a pesar de que ambos están usando la misma versión de .NET/C#.

¿Alguien puede explicar qué está saliendo mal en la aplicación de consola? Gracias.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    El problema con el valor nulo de la variable expr es probablemente debido al hecho de que el atributo CallerArgumentExpression depende de que el llamador pase la expresión del argumento al método. En una aplicación de consola, el llamador podría no estar pasando la expresión de la forma esperada, lo que provoca que sea nula.

    Una solución potencial podría ser utilizar el atributo CallerMemberName en lugar de CallerArgumentExpression, lo cual recuperaría automáticamente el nombre del miembro que hace la llamada (método, propiedad o campo) y lo utilizaría como expresión de argumento. Esto eliminaría la necesidad de que el llamador pase explícitamente la expresión.

    Sin embargo, esto podría no funcionar en el caso de los registros, ya que sus miembros se generan automáticamente y podrían no tener un patrón de nombres consistente.

    Otra solución podría ser pasar explícitamente la expresión del argumento como un parámetro de cadena a los métodos de validación, en lugar de depender del atributo CallerArgumentExpression. Esto aseguraría que la expresión siempre se pasa correctamente, independientemente del contexto de llamada.

    También es posible que haya diferencias sutiles entre LinqPad y la aplicación de consola en cuanto a cómo se compila o ejecuta el código, lo que podría afectar el comportamiento del atributo CallerArgumentExpression.

    En general, podría requerir algo de experimentación y ajustes para obtener el comportamiento deseado en la aplicación de consola.

Comments are closed.