Adnotacje parametrów typu nieograniczonego
Notatka
Ten artykuł jest specyfikacją funkcji. Specyfikacja służy jako dokument projektowy dla funkcji. Zawiera proponowane zmiany specyfikacji wraz z informacjami wymaganymi podczas projektowania i opracowywania funkcji. Te artykuły są publikowane do momentu sfinalizowania proponowanych zmian specyfikacji i włączenia ich do obecnej specyfikacji ECMA.
Mogą wystąpić pewne rozbieżności między specyfikacją funkcji a ukończoną implementacją. Te różnice są uchwycone w notatkach ze spotkań dotyczących projektu języka (LDM).
Więcej informacji na temat procesu wdrażania specyfikacji funkcji można znaleźć w standardzie języka C# w artykule dotyczącym specyfikacji .
Problem z mistrzem: https://github.com/dotnet/csharplang/issues/3297
Streszczenie
Zezwalaj na adnotacje nullable dla parametrów typu, które nie ograniczają się do typów wartości lub typów odwołań: T?
.
static T? FirstOrDefault<T>(this IEnumerable<T> collection) { ... }
adnotacja ?
W języku C#8 adnotacje ?
można zastosować tylko do parametrów typu, które były jawnie ograniczone do typów wartości lub typów odwołań.
W języku C#9 adnotacje ?
można zastosować do dowolnego parametru typu, niezależnie od ograniczeń.
Jeśli parametr typu nie jest jawnie ograniczony do typów wartości, adnotacje można stosować tylko w kontekście #nullable enable
.
Jeśli parametr typu T
zostanie zastąpiony typem referencyjnym, to T?
reprezentuje pustą instancję tego typu referencyjnego, która akceptuje wartość null.
var s1 = new string[0].FirstOrDefault(); // string? s1
var s2 = new string?[0].FirstOrDefault(); // string? s2
Jeśli T
jest zastępowany typem wartości, T?
reprezentuje wystąpienie T
.
var i1 = new int[0].FirstOrDefault(); // int i1
var i2 = new int?[0].FirstOrDefault(); // int? i2
Jeśli T
jest zastępowany typem adnotacji U?
, T?
reprezentuje typ adnotacji U?
, a nie U??
.
var u1 = new U[0].FirstOrDefault(); // U? u1
var u2 = new U?[0].FirstOrDefault(); // U? u2
Jeśli T
jest zastępowany typem U
, T?
reprezentuje U?
, nawet w kontekście #nullable disable
.
#nullable disable
var u3 = new U[0].FirstOrDefault(); // U? u3
W przypadku wartości zwracanych T?
jest równoważne [MaybeNull]T
; dla wartości argumentów T?
jest równoważna [AllowNull]T
.
Równoważność jest ważna podczas zastępowania lub implementowania interfejsów z zestawu skompilowanego przy użyciu języka C#8.
public abstract class A
{
[return: MaybeNull] public abstract T F1<T>();
public abstract void F2<T>([AllowNull] T t);
}
public class B : A
{
public override T? F1<T>() where T : default { ... } // matches A.F1<T>()
public override void F2<T>(T? t) where T : default { ... } // matches A.F2<T>()
}
ograniczenie default
Aby uzyskać zgodność z istniejącym kodem, w którym zastępowane i jawnie implementowane metody ogólne nie mogą zawierać jawnych klauzul ograniczeń, T?
w przesłoniętej lub jawnie zaimplementowanej metodzie jest traktowana jako Nullable<T>
, gdzie T
jest typem wartości.
Aby zezwolić na adnotacje dotyczące parametrów typu ograniczonych do typów odwołań, C#8 pozwolił na jawne where T : class
i where T : struct
ograniczenia w odniesieniu do metod zastępowanych lub jawnie zaimplementowanych.
class A1
{
public virtual void F1<T>(T? t) where T : struct { }
public virtual void F1<T>(T? t) where T : class { }
}
class B1 : A1
{
public override void F1<T>(T? t) /*where T : struct*/ { }
public override void F1<T>(T? t) where T : class { }
}
Aby zezwolić na adnotacje dla parametrów typu, które nie są ograniczone do typów odwołań lub typów wartości, język C#9 zezwala na nowe ograniczenie where T : default
.
class A2
{
public virtual void F2<T>(T? t) where T : struct { }
public virtual void F2<T>(T? t) { }
}
class B2 : A2
{
public override void F2<T>(T? t) /*where T : struct*/ { }
public override void F2<T>(T? t) where T : default { }
}
Jest błędem używanie ograniczenia default
w innych przypadkach niż zastąpienie metody lub jawna implementacja.
Używanie ograniczenia default
jest błędem, kiedy parametr typu w metodzie przeciążonej lub interfejsowej jest ograniczony do typu referencyjnego lub typu wartościowego.
Spotkania projektowe
C# feature specifications