[Bug]: Nullable implicit operator on string extensible enums still throws for a null string

Abierto Apto para principiantes
#12,572 1 comentario 1 reacción 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
84/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
csharp
Área
backend, tooling

Línea de trabajo

Empieza en packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ExtensibleEnumProvider.cs, en la emisión del operador implícito nullable alrededor de las líneas 190–196, y luego lee las pruebas relacionadas en TestProjects/Local.Tests/ExtensibleEnumTests.cs. Añade la prueba que convierte una variable de cadena null a StringExtensibleEnum? y confirma que devuelve null; el operador emitido debería asignar al caso null el tipo enum nullable.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

bug emitter:client:csharp
Describe the bug

#7966 still reproduces after #7967. Converting a null string to a nullable string extensible enum throws ArgumentNullException instead of returning null. The operator added in #7967 is emitted as:

public static implicit operator StringExtensibleEnum?(string value) => value == null ? null : new StringExtensibleEnum(value);

The conditional's natural type is StringExtensibleEnum, not StringExtensibleEnum?: the untyped null converts to it through the generated implicit operator StringExtensibleEnum(string). So the null branch calls that operator with null, and the constructor's Argument.AssertNotNull throws.

The tests added in #7967 pass because they only use the null literal (NullableExtensibleEnumMethod(null), StringExtensibleEnum? nullFoo = null;). C# converts a null literal to Nullable<T> directly, so neither test calls the new operator.

Every string extensible enum emitted since #7967 has this operator. Azure.ResourceManager.Search hand-wrote a corrected copy for one of its enums to get null handling to work (discussion).

Suggested fix: in ExtensibleEnumProvider.cs, give the null branch the nullable type, e.g. Null.CastTo(Type.WithNullable(true)), so the output becomes value == null ? (StringExtensibleEnum?)null : new StringExtensibleEnum(value).

Reproduction

StringExtensibleEnum below has the same constructor and implicit operators as the generated StringExtensibleEnum.cs, with Argument.AssertNotNull inlined so it runs standalone.

using System;

string value = null;

try
{
    StringExtensibleEnum? e = value;
    Console.WriteLine($"HasValue={e.HasValue}");
}
catch (ArgumentNullException ex)
{
    Console.WriteLine($"{ex.GetType().Name}: {ex.Message}");
}

public readonly struct StringExtensibleEnum
{
    private readonly string _value;

    public StringExtensibleEnum(string value)
    {
        _value = value ?? throw new ArgumentNullException(nameof(value));
    }

    public static implicit operator StringExtensibleEnum(string value) => new StringExtensibleEnum(value);

    public static implicit operator StringExtensibleEnum?(string value) => value == null ? null : new StringExtensibleEnum(value);
}

Output on .NET 8:

ArgumentNullException: Value cannot be null. (Parameter 'value')

With the null branch cast to (StringExtensibleEnum?)null, it prints HasValue=False.

A test in TestProjects/Local.Tests/ExtensibleEnumTests.cs that exercises the operator:

[Test]
public void ConvertingNullStringToNullableExtensibleEnumDoesNotThrow()
{
    string? value = null;
    StringExtensibleEnum? e = value;
    Assert.IsNull(e);
}
Checklist

🤖 m-nash-copilot

Lenguaje dominante
Java
Estrellas
5.9k
Forks
421
Merge medio
2 d 3 h
PR fusionados (30 d)
176

Preparar el entorno

Abrir en Codespaces

Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de microsoft/typespec

Todos los issues de microsoft/typespec

Issues similares

Más issues de Java

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.