Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este documento se enumeran los cambios importantes conocidos en Roslyn después de la versión general de .NET 7 (versión 7.0.100 del SDK de .NET) hasta la versión general de .NET 8 (versión 8.0.100 del SDK de .NET).
Los modificadores ref de argumentos dinámicos deben ser compatibles con modificadores ref de los parámetros correspondientes.
Introducido en Visual Studio 2022, versión 17.10
Los modificadores ref de argumentos dinámicos deben ser compatibles con los modificadores ref de los parámetros correspondientes durante la compilación. Esto puede provocar un fallo en la resolución de una sobrecarga que implique argumentos dinámicos en tiempo de compilación en lugar de en tiempo de ejecución.
Anteriormente, se permitía un desajuste en tiempo de compilación, lo que retrasaba el fallo de resolución de sobrecarga hasta el tiempo de ejecución.
Por ejemplo, el siguiente código solía compilarse sin errores, pero producía un error con la excepción: "Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: El mejor método sobrecargado para 'C.f(ref object)' tiene algunos argumentos no válidos". Ahora produce un error de compilación.
public class C
{
public void f(ref dynamic a)
{
}
public void M(dynamic d)
{
f(d); // error CS1620: Argument 1 must be passed with the 'ref' keyword
}
}
La expresión de colección para la implementación de tipos IEnumerable
debe tener elementos convertibles implícitamente a object
Introducido en Visual Studio 2022, versión 17.10
La conversión de una expresión de colección a un struct
o class
que implementa System.Collections.IEnumerable
y no tiene un GetEnumerator()
fuertemente tipado requiere que los elementos de la expresión de colección se conviertan implícitamente a object
.
Anteriormente, se supone que los elementos de una expresión de colección que tienen como destino una IEnumerable
implementación se pueden convertir a object
y se convierten solo cuando se enlazan al método aplicable Add
.
Este requisito adicional significa que la conversión de expresiones de colección a implementaciones IEnumerable
se trata de forma coherente con otros tipos de destino en los que los elementos de la expresión de colección se deben convertir implícitamente en el tipo de iteración del tipo de destino.
Este cambio afecta a las expresiones de colección dirigidas a implementaciones IEnumerable
donde los elementos dependen de la tipificación por destino para un tipo de parámetro de método Add
fuertemente tipado.
En el ejemplo siguiente, se notifica un error que _ => { }
no se puede convertir implícitamente en object
.
class Actions : IEnumerable
{
public void Add(Action<int> action);
// ...
}
Actions a = [_ => { }]; // error CS8917: The delegate type could not be inferred.
Para resolver el error, la expresión de elemento podría escribirse explícitamente.
a = [(int _) => { }]; // ok
a = [(Action<int>)(_ => { })]; // ok
El tipo de destino de la expresión de colección debe tener un constructor y un método Add
Introducido en Visual Studio 2022, versión 17.10
La conversión de una expresión de colección a un struct
o class
que implementa System.Collections.IEnumerable
y no tiene un CollectionBuilderAttribute
requiere que el tipo de destino tenga un constructor accesible al que se pueda llamar sin argumentos y, si la expresión de colección no está vacía, el tipo de destino debe tener un método accesible Add
que se pueda llamar con un único argumento.
Anteriormente, el constructor y los métodos Add
eran necesarios para la construcción de la instancia de colección, pero no para la conversión.
Esto significaba que la siguiente llamada era ambigua, ya que tanto char[]
como string
eran tipos de destino válidos para la expresión de colección.
La llamada ya no es ambigua porque string
no tiene un constructor o Add
método sin parámetros.
Print(['a', 'b', 'c']); // calls Print(char[])
static void Print(char[] arg) { }
static void Print(string arg) { }
Los argumentos ref
se pueden pasar a parámetros in
Introducido en Visual Studio 2022, versión 17.8p2
Los parámetros de la característica ref readonly
relajan la resolución de sobrecarga, lo que permite pasar argumentos ref
a parámetros in
cuando LangVersion
se establece en 12 o posterior.
Esto puede provocar cambios importantes en el comportamiento o la fuente.
var i = 5;
System.Console.Write(new C().M(ref i)); // prints "E" in C# 11, but "C" in C# 12
System.Console.Write(E.M(new C(), ref i)); // workaround: prints "E" always
class C
{
public string M(in int i) => "C";
}
static class E
{
public static string M(this C c, ref int i) => "E";
}
var i = 5;
System.Console.Write(C.M(null, ref i)); // prints "1" in C# 11, but fails with an ambiguity error in C# 12
System.Console.Write(C.M((I1)null, ref i)); // workaround: prints "1" always
interface I1 { }
interface I2 { }
static class C
{
public static string M(I1 o, ref int x) => "1";
public static string M(I2 o, in int x) => "2";
}
Preferir el desecho basado en patrones en lugar de basado en interfaces en using
asincrónico
Introducido en Visual Studio 2022, versión 17.10p3
Un using
asincrónico prefiere enlazar usando un método DisposeAsync()
basado en un patrón en lugar de IAsyncDisposable.DisposeAsync()
basado en interfaz.
Por ejemplo, se seleccionará el método público DisposeAsync()
, en lugar de la implementación de la interfaz privada:
await using (var x = new C()) { }
public class C : System.IAsyncDisposable
{
ValueTask IAsyncDisposable.DisposeAsync() => throw null; // no longer picked
public async ValueTask DisposeAsync()
{
Console.WriteLine("PICKED");
await Task.Yield();
}
}
Roslyn breaking changes