Sdílet prostřednictvím


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