Niet-getrainde typeparameteraantekeningen
Notitie
Dit artikel is een functiespecificatie. De specificatie fungeert als het ontwerpdocument voor de functie. Het bevat voorgestelde specificatiewijzigingen, samen met informatie die nodig is tijdens het ontwerp en de ontwikkeling van de functie. Deze artikelen worden gepubliceerd totdat de voorgestelde specificaties zijn voltooid en opgenomen in de huidige ECMA-specificatie.
Er kunnen enkele verschillen zijn tussen de functiespecificatie en de voltooide implementatie. Deze verschillen worden vastgelegd in de notities van de Language Design Meeting (LDM) .
Meer informatie over het proces voor het aannemen van functiespeclets in de C#-taalstandaard vindt u in het artikel over de specificaties.
Kampioenprobleem: https://github.com/dotnet/csharplang/issues/3297
Samenvatting
Sta niet-nullable-annotaties toe voor typeparameters die niet zijn beperkt tot waardetypen of referentietypen: T?
.
static T? FirstOrDefault<T>(this IEnumerable<T> collection) { ... }
aantekening ?
In C#8 konden ?
aantekeningen alleen worden toegepast op typeparameters die expliciet zijn beperkt tot waardetypen of verwijzingstypen.
In C#9 kunnen ?
aantekeningen worden toegepast op elke typeparameter, ongeacht de beperkingen.
Tenzij een typeparameter expliciet is beperkt tot waardetypen, kunnen aantekeningen alleen worden toegepast binnen een #nullable enable
context.
Als een typeparameter T
wordt vervangen door een verwijzingstype, T?
een null-exemplaar van dat verwijzingstype vertegenwoordigt.
var s1 = new string[0].FirstOrDefault(); // string? s1
var s2 = new string?[0].FirstOrDefault(); // string? s2
Als T
wordt vervangen door een waardetype, vertegenwoordigt T?
een exemplaar van T
.
var i1 = new int[0].FirstOrDefault(); // int i1
var i2 = new int?[0].FirstOrDefault(); // int? i2
Als T
wordt vervangen door een geannoteerd type U?
, vertegenwoordigt T?
het geannoteerde type U?
in plaats van U??
.
var u1 = new U[0].FirstOrDefault(); // U? u1
var u2 = new U?[0].FirstOrDefault(); // U? u2
Als T
wordt vervangen door een type U
, vertegenwoordigt T?
U?
, zelfs binnen een #nullable disable
context.
#nullable disable
var u3 = new U[0].FirstOrDefault(); // U? u3
Voor retourwaarden is T?
gelijk aan [MaybeNull]T
; voor argumentwaarden is T?
gelijk aan [AllowNull]T
.
De gelijkwaardigheid is belangrijk bij het overschrijven of implementeren van interfaces van een assembly die is gecompileerd met 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>()
}
default
beperking
Voor compatibiliteit met bestaande code waarbij overschreven en expliciet geïmplementeerde algemene methoden geen expliciete beperkingsclausules konden bevatten, wordt T?
in een overschreven of expliciet geïmplementeerde methode behandeld als Nullable<T>
waarbij T
een waardetype is.
Om aantekeningen toe te staan voor typeparameters die zijn beperkt tot referentietypen, maakt C#8 het mogelijk om expliciete where T : class
- en where T : struct
-beperkingen toe te passen op de overschreven of expliciet geïmplementeerde methode.
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 { }
}
Als u aantekeningen wilt toestaan voor typeparameters die niet zijn beperkt tot verwijzingstypen of waardetypen, staat C#9 een nieuwe where T : default
beperking toe.
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 { }
}
Het is een vergissing om een default
beperking te gebruiken anders dan bij een methode-override of expliciete implementatie.
Het is een fout bij het gebruik van een default
beperking wanneer de overeenkomstige typeparameter in de overschreven methode of interfacemethode wordt beperkt tot een verwijzingstype of waardetype.
Ontwerpbijeenkomsten
C# feature specifications