Neomezené anotace parametrů typu
Poznámka
Tento článek je specifikace funkce. Specifikace slouží jako návrhový dokument pro funkci. Zahrnuje navrhované změny specifikace spolu s informacemi potřebnými při návrhu a vývoji funkce. Tyto články se publikují, dokud nebudou navrhované změny specifikace finalizovány a začleněny do aktuální specifikace ECMA.
Mezi specifikací funkce a dokončenou implementací může docházet k nějakým nesrovnalostem. Tyto rozdíly jsou zachyceny v poznámkách příslušné schůzky návrhu jazyka (LDM) .
Další informace o procesu přijetí specifikací funkcí do jazyka C# najdete v článku o specifikacích .
Problém šampiona: https://github.com/dotnet/csharplang/issues/3297
Shrnutí
Povolit nulovatelné anotace pro parametry typů, které nejsou omezeny na hodnotové nebo odkazové typy: T?
.
static T? FirstOrDefault<T>(this IEnumerable<T> collection) { ... }
?
poznámky
V jazyce C#8 lze ?
poznámky použít pouze u parametrů typu, které byly explicitně omezeny na typy hodnot nebo odkazové typy.
V jazyce C#9 se ?
poznámky dají použít u libovolného parametru typu bez ohledu na omezení.
Pokud není parametr typu explicitně omezen na typy hodnot, lze poznámky použít pouze v rámci #nullable enable
kontextu.
Pokud je parametr typu T
nahrazen odkazovým typem, T?
představuje instanci tohoto typu odkazu s možnou hodnotou null.
var s1 = new string[0].FirstOrDefault(); // string? s1
var s2 = new string?[0].FirstOrDefault(); // string? s2
Pokud je T
nahrazena typem hodnoty, pak T?
představuje instanci T
.
var i1 = new int[0].FirstOrDefault(); // int i1
var i2 = new int?[0].FirstOrDefault(); // int? i2
Pokud T
nahradí U?
anotovaným typem , T?
představuje U?
anotovaný typ, nikoli U??
.
var u1 = new U[0].FirstOrDefault(); // U? u1
var u2 = new U?[0].FirstOrDefault(); // U? u2
Pokud se T
nahradí typem U
, pak T?
představuje U?
, a to i v kontextu #nullable disable
.
#nullable disable
var u3 = new U[0].FirstOrDefault(); // U? u3
Pro návratové hodnoty je T?
ekvivalentní [MaybeNull]T
; pro hodnoty argumentů je T?
ekvivalentní [AllowNull]T
.
Ekvivalence je důležitá při přepsání nebo implementaci rozhraní ze sestavení zkompilovaného pomocí jazyka 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>()
}
omezení default
Pro zajištění kompatibility se stávajícím kódem, kde přepsané a explicitně implementované obecné metody nemohou zahrnovat explicitní klauzule omezení, se T?
v přepsané nebo explicitně implementované metodě považuje za Nullable<T>
, kde T
je hodnotový typ.
Chcete-li povolit poznámky pro parametry typu omezené na odkazové typy, v C#8 byla povolena explicitní omezení pomocí where T : class
a where T : struct
na přepsaných nebo explicitně implementovaných metodách.
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 { }
}
Chcete-li povolit poznámky pro parametry typu, které nejsou omezeny na odkazové typy nebo typy hodnot, C#9 umožňuje nové omezení 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 { }
}
Jedná se o chybu použití jiného omezení default
než u přepsání metody nebo explicitní implementace.
Jedná se o chybu, když použijete omezení default
, pokud je odpovídající parametr typu v přepsané metodě nebo metodě rozhraní omezen na referenční nebo hodnotový typ.
Projektové schůzky
C# feature specifications