Share via


Fouten en waarschuwingen met betrekking tot algemene typeparameters en algemene typeargumenten oplossen

In dit artikel worden de volgende compilerfouten behandeld:

  • CS0080: Beperkingen zijn niet toegestaan voor niet-algemene declaraties.
  • CS0081: Typeparameterdeclaratie moet een id zijn, niet een type.
  • CS0224: Een methode met vararg kan niet algemeen zijn, zich in een algemeen type bevinden of een parameter params hebben.
  • CS0304: Kan geen exemplaar van het variabeletype maken omdat deze niet de new() beperking heeft.
  • CS0305: Voor het gebruik van het algemene type zijn N-typeargumenten vereist.
  • CS0306: Het type kan niet worden gebruikt als een typeargument.
  • CS0307: De identifier is geen generieke methode. Als u een expressielijst bedoelde, gebruik dan haakjes rond de expressie.
  • CS0308: Het niet-algemene type-of-methode kan niet worden gebruikt met typeargumenten.
  • CS0310: Het type moet een niet-abstract type zijn met een openbare parameterloze constructor om dit te kunnen gebruiken als parameter in het algemene type of de methode.
  • CS0311: Het type kan niet worden gebruikt als typeparameter T in het algemene type of de methode. Er is geen impliciete verwijzingsconversie van type1 naar type2.
  • CS0312: Het type 'type1' kan niet worden gebruikt als typeparameter in het algemene type of de methode. Het null-type 'type1' voldoet niet aan de beperking.
  • CS0313: Het type 'type1' kan niet worden gebruikt als typeparameter in het algemene type of de methode. Het null-type 'type1' voldoet niet aan de beperking. Null-typen kunnen niet voldoen aan interfacebeperkingen.
  • CS0314: Het type kan niet worden gebruikt als typeparameter in het generieke type of de methode. Er is geen boxing-conversie of type-parameterconversie.
  • CS0315: Het type kan niet worden gebruikt als typeparameter T in het generieke type of de methode. Er is geen boxing-conversie.
  • CS0401: De new() beperking moet de laatste opgegeven beperking zijn.
  • CS0403: Kan null niet converteren naar typeparameter omdat het een niet-null-waardetype kan zijn. Overweeg in plaats daarvan te gebruiken default(T) .
  • CS0405: Dubbele beperking voor typeparameter.
  • CS0412: Parameter: een parameter, lokale variabele of lokale functie mag niet dezelfde naam hebben als een parameter van het methodetype.
  • CS0413: De typeparameter kan niet worden gebruikt met de as operator omdat deze geen klassetypebeperking of een class beperking heeft.
  • CS0417: Kenmerk: kan geen argumenten opgeven bij het instantiëren van een variabele-type.
  • CS0449: De classbeperkingen , struct, unmanageden notnulldefault beperkingen kunnen niet worden gecombineerd of gedupliceerd en moeten eerst worden opgegeven in de lijst met beperkingen.
  • CS0450: Type parameter: kan niet zowel een beperkingsklasse als de class of struct beperking opgeven.
  • CS0451: De new() beperking kan niet worden gebruikt met de struct beperking.
  • CS0454: Afhankelijkheid van kringbeperking met typeparameter 1 en typeparameter 2.
  • CS0455: De parameter Type neemt conflicterende beperkingen over.
  • CS0694: De parameter Type heeft dezelfde naam als het type of de methode die de parameter bevat.
  • CS0695: T kan beide interfaces niet implementeren, omdat ze mogelijk samenbrengen voor bepaalde typeparametervervangingen.
  • CS0698: Een algemeen type kan niet worden afgeleid van het type omdat het een kenmerkklasse is.
  • CS0702: Beperking kan geen speciale klasse zijn.
  • CS0703: Inconsistente toegankelijkheid: het restrictietype is minder toegankelijk dan de declaratie.
  • CS0706: Ongeldig beperkingstype. Een type dat als beperking wordt gebruikt, moet een interface, een niet-verzegelde klasse of een typeparameter zijn.
  • CS0717: Statische klasse: statische klassen kunnen niet als beperkingen worden gebruikt.
  • CS1961: Ongeldige variantie: de typeparameter moet geldig variant zijn op het type.
  • CS7002: Onverwacht gebruik van een algemene naam.
  • CS8322: Kan argument met dynamisch type niet doorgeven aan algemene lokale functie met afgeleide typeargumenten.
  • CS9011: Trefwoord delegate kan niet worden gebruikt als een beperking. Bedoel je System.Delegate?
  • CS9012: Onverwacht trefwoord record. Bedoelde je record struct of record class?
  • CS9338: Inconsistente toegankelijkheid: type is minder toegankelijk dan klasse.

Typeparameterdeclaratie en naamgeving

De volgende fouten hebben betrekking op de manier waarop u typeparameters declareert en benoemt in generieke typen en methoden.

  • CS0080: Beperkingen zijn niet toegestaan voor niet-algemene declaraties.
  • CS0081: Typeparameterdeclaratie moet een id zijn, niet een type.
  • CS0412: Parameter: een parameter, lokale variabele of lokale functie mag niet dezelfde naam hebben als een parameter van het methodetype.
  • CS0694: De parameter Type heeft dezelfde naam als het type of de methode die de parameter bevat.
  • CS9012: Onverwacht trefwoord record. Bedoelde je record struct of record class?

Als u deze fouten wilt corrigeren, moet u ervoor zorgen dat u typeparameters declareert met geldige id's, alleen beperkingsclausules toepast op algemene declaraties en conflicten met andere id's in het bereik voorkomen:

  • Verwijder de beperkingscomponent uit niet-algemene declaraties (CS0080). De where component kan alleen worden gebruikt voor algemene typen en methoden die typeparameters declareren, omdat beperkingen vereisten definiëren waaraan typeargumenten moeten voldoen. Als u beperkingen wilt toepassen, voegt u eerst typeparameters toe aan uw type- of methodedeclaratie. Wijzig bijvoorbeeld public class MyClass where MyClass : System.IDisposable in public class MyClass<T> where T : System.IDisposable.
  • Vervang de werkelijke typenamen door identificaties in typeparameterdeclaraties (CS0081). U moet typeparameters declareren met behulp van id's (zoals T, TKeyof TValue) in plaats van betontypen (zoals int of string). Het doel van een typeparameter is om te fungeren als een tijdelijke aanduiding die de compiler vervangt door werkelijke typen wanneer het algemene type of de methode wordt gebruikt. Wijzig bijvoorbeeld public void F<int>() in public void F<T>().
  • Wijzig de naam van parameters, lokale variabelen of parameters om naamconflicten (CS0412, CS0694) te voorkomen. Typeparameternamen kunnen geen identifiers in dezelfde scope overschrijven. Ze kunnen de naam niet overeen laten komen met het type of de methode waarin het zich bevindt. Dergelijke conflicten zorgen voor dubbelzinnigheid over de id waarnaar wordt verwezen. Als u bijvoorbeeld een methode public void F<T>()hebt, kunt u geen lokale variabele double T binnen die methode declareren en kunt u een typeparameter niet dezelfde naam geven als het bijbehorende type (class C<C>).
  • Gebruik de juiste syntaxis voor recorddeclaratie (CS9012). Bij het declareren van een recordtype moet u een record class of record struct (of alleen record voor een verwijzingstype) gebruiken. Het record trefwoord alleen kan niet worden weergegeven in posities waarin de compiler een syntaxis van een typedeclaratie verwacht. Als u bijvoorbeeld een recordtype wilt declareren, schrijven record class MyRecord of record struct MyRecord in plaats van te plaatsen record waar een ander trefwoord wordt verwacht.

Zie Algemene typeparameters en generics voor meer informatie.

Declaratie en volgorde van beperkingen

De volgende fouten hebben betrekking op de syntaxis en volgorde van beperkingen voor algemene typeparameters:

  • CS0401: De new() beperking moet de laatste opgegeven beperking zijn.
  • CS0449: De classbeperkingen , struct, unmanageden notnulldefault beperkingen kunnen niet worden gecombineerd of gedupliceerd en moeten eerst worden opgegeven in de lijst met beperkingen.
  • CS0450: Type parameter: kan niet zowel een beperkingsklasse als de class of struct beperking opgeven.
  • CS0451: De new() beperking kan niet worden gebruikt met de struct beperking.
  • CS9011: Trefwoord delegate kan niet worden gebruikt als een beperking. Bedoel je System.Delegate?

Beperkingen voor typeparameters moeten een specifieke volgorde volgen: primaire beperkingen (class, struct, unmanaged, notnullof default) komen eerst voor, gevolgd door interface- of klassebeperkingen en ten slotte de new() constructorbeperking. Sommige beperkingen sluiten elkaar wederzijds uit en kunnen niet worden gecombineerd.

Ga als volgt te werk om deze fouten te corrigeren:

  • Plaats de new() beperking aan het einde van de lijst met beperkingen (CS0401). De new() beperking moet na alle andere beperkingen worden weergegeven. Wijzig bijvoorbeeld where T : new(), IDisposable in where T : IDisposable, new().
  • Plaats primaire beperkingen eerst en combineer geen wederzijds exclusieve beperkingen (CS0449). U kunt maximaal één van class, struct, unmanagedof notnull, of default, opgeven en deze moet eerst worden weergegeven in de lijst met beperkingen. De class en struct beperkingen sluiten elkaar wederzijds uit, zoals en classunmanaged . In een null-context impliceert class al notnull, zodat ze niet kunnen worden gecombineerd.
  • Combineer geen specifieke klassebeperking met struct (CS0450). Als een typeparameter is beperkt tot een specifiek klassetype, is dit impliciet een verwijzingstype dat in strijd is met de struct beperking. Verwijder de klassebeperking of de struct beperking.
  • Combineer niet new() met struct (CS0451). Alle waardetypen (structs) hebben impliciet een openbare parameterloze constructor, dus de new() beperking is redundant wanneer deze wordt gecombineerd met struct. Verwijder de new() beperking wanneer u struct gebruikt.
  • Vervang delegate door System.Delegate in beperkingsclausules (CS9011). Het delegate trefwoord wordt gebruikt voor het declareren van gedelegeerdentypen, niet als een beperking. Als u een typeparameter wilt beperken om typen te delegeren, gebruikt System.Delegate u deze als beperkingstype. Wijzig bijvoorbeeld where T : delegate in where T : System.Delegate.

In het volgende voorbeeld ziet u de juiste volgorde van beperkingen:

using System;

// Primary constraint first, then interface constraints, then new()
class C<T> where T : class, IDisposable, new() { }

// struct doesn't need new() - it's implicit
class D<T> where T : struct, IComparable { }

// Delegate constraint using System.Delegate
class E<T> where T : System.Delegate { }

Zie Beperkingen voor typeparameters voor meer informatie.

Aantal type argumenten en gebruik

De volgende fouten hebben betrekking op het opgeven van het juiste aantal en het juiste typeargumenten voor algemene typen en methoden:

  • CS0224: Een methode met vararg kan niet algemeen zijn, zich in een algemeen type bevinden of een parameter params hebben.
  • CS0305: Voor het gebruik van het algemene type zijn N-typeargumenten vereist.
  • CS0306: Het type kan niet worden gebruikt als een typeargument.
  • CS0307: De identifier is geen generieke methode. Als u een lijst van expressies hebt bedoeld, gebruik haakjes rond de expressie.
  • CS0308: Het niet-generieke type of methode kan niet worden gebruikt met typeargumenten.
  • CS7002: Onverwacht gebruik van een algemene naam.

Als u deze fouten wilt corrigeren, moet u ervoor zorgen dat u het exacte aantal typeargumenten opgeeft dat is vereist voor de algemene declaratie. Gebruik alleen geldige typen als typeargumenten. Typargumenten niet toepassen op niet-algemene constructies:

  • Verwijder algemene typeparameters of algemene typedeclaraties uit methoden die worden gebruikt __arglist (CS0224). Het __arglist trefwoord is niet compatibel met generics omdat de runtimemechanismen voor het verwerken van variabele argumenten conflicteren met het type vervangen dat vereist is voor algemene typeparameters. Deze beperking is ook van toepassing op het params trefwoord wanneer het wordt gebruikt in combinatie met algemene methoden of methoden binnen algemene typen.
  • Geef het exacte aantal typeargumenten op dat is opgegeven in de algemene type- of methodedeclaratie (CS0305). Elke algemene typeparameter die in de definitie is gedeclareerd, moet een bijbehorend typeargument hebben wanneer het algemene type wordt geïnstantieerd. De compiler moet weten welk betontype moet worden vervangen door elke typeparameter. Als een klasse bijvoorbeeld wordt gedeclareerd als class MyList<T>, moet u precies één typeargument opgeven wanneer u deze gebruikt, bijvoorbeeld MyList<int>, niet MyList<int, string>.
  • Gebruik alleen geldige typen als typeargumenten (CS0306). Aanwijzertypen, zoals int* of char*, kunnen niet worden gebruikt als typeargumenten omdat voor algemene typen beheerde typen zijn vereist die door de garbagecollector kunnen worden bijgehouden en aanwijzertypen onbeheerd zijn. Als u met pointers in een algemene context wilt werken, kunt u overwegen uw code te gebruiken IntPtr of te herstructureren om te voorkomen dat generieken met onveilige code worden gemengd.
  • Verwijder de syntaxis van het typeargument uit niet-algemene constructies (CS0307, CS0308). Typeargumenten tussen punthaken (zoals <int>) kunnen alleen worden toegepast op algemene typen en methoden die typeparameters declareren. U moet de typeargumenten geheel verwijderen of ervoor zorgen dat u de naamruimte hebt geïmporteerd die de algemene versie van het type bevat. Bijvoorbeeld, IEnumerator<T> vereist de using System.Collections.Generic; richtlijn, terwijl IEnumerator zich in System.Collections bevindt.
  • Typeparameters verwijderen uit declaraties die geen ondersteuning bieden voor generics (CS7002). Sommige constructies, zoals opsommingen, kunnen niet algemeen zijn. Als u een algemene container voor enum-waarden nodig hebt, kunt u in plaats daarvan een algemene klasse of struct gebruiken.

Zie Algemene typeparameters en generics voor meer informatie.

Constructorbeperkingen

De volgende fouten hebben betrekking op de new() beperking voor algemene typeparameters:

  • CS0304: Kan geen exemplaar van het variabeletype maken omdat deze niet de new() beperking heeft.
  • CS0310: Het type moet een niet-abstract type zijn met een openbare parameterloze constructor om dit te kunnen gebruiken als parameter in het algemene type of de methode.
  • CS0417: Identificator: kan geen argumenten opgeven bij het maken van een instantie van een variabele type.

Als u deze fouten wilt corrigeren, voegt u de new() beperking toe aan het typeparameters die moeten worden geïnstantieerd, zorgt u ervoor dat typeargumenten openbare parameterloze constructors hebben en vermijdt u het doorgeven van argumenten bij het maken van exemplaren van typeparameters:

  • Voeg de new() beperking toe aan de parameterdeclaratie van het type (CS0304). Wanneer u de new operator gebruikt om een exemplaar van een typeparameter te maken binnen een algemeen type of een algemene methode, moet de compiler kunnen garanderen dat elk typeargument dat tijdens runtime wordt opgegeven, een parameterloze constructor beschikbaar heeft. De new() beperking biedt deze garantie tijdens het compileren, zodat de compiler de juiste instantiecode kan genereren. Als u bijvoorbeeld een lid class C<T>hebtT t = new T();, moet u de declaratie wijzigen in class C<T> where T : new().
  • Zorg ervoor dat typeargumenten die worden gebruikt met beperkte typeparameters openbare parameterloze constructors (new()) hebben. Wanneer een algemeen type of methode een new() beperking voor een typeparameter declareert, moet elk concreet type dat als een typeargument wordt gebruikt, niet-abstract zijn en een openbare parameterloze constructor opgeven. Als een type alleen niet-openbare constructors (zoals private of protected constructors) heeft of alleen constructors met parameters heeft, kan het niet voldoen aan de new() beperking. Als u deze fout wilt oplossen, voegt u een openbare parameterloze constructor toe aan het type of gebruikt u een ander typeargument dat er al een heeft.
  • Constructorargumenten verwijderen bij het instantiëren van typeparameters (CS0417). De new() beperking garandeert alleen het bestaan van een parameterloze constructor, zodat u geen argumenten new T(arguments) kunt doorgeven omdat de compiler niet kan verifiëren dat een constructor met deze specifieke parametertypen bestaat op de typen die worden vervangen door T. Als u exemplaren met specifieke argumenten wilt maken, kunt u overwegen om fabrieksmethoden, abstracte factorypatronen of specifieke basisklasse- of interfacebeperkingen te gebruiken die het bouwgedrag definiëren dat u nodig hebt.

Zie Beperkingen voor typeparameters en de new() beperking voor meer informatie.

Tevredenstelling en transformaties van beperkingen

De volgende fouten hebben betrekking op typeargumenten die niet voldoen aan de beperkingen van algemene typeparameters:

  • CS0311: Het type kan niet worden gebruikt als typeparameter T in het algemene type of de methode. Er is geen impliciete verwijzingsconversie.
  • CS0312: Het type kan niet worden gebruikt als typeparameter in het algemene type of de methode. Het type null voldoet niet aan de beperking.
  • CS0313: Het type kan niet worden gebruikt als typeparameter in het algemene type of de methode. Het type null voldoet niet aan de beperking. Null-typen kunnen niet voldoen aan interfacebeperkingen.
  • CS0314: Het type kan niet worden gebruikt als de typeparameter in het generieke type of de methode. Er is geen boxing-conversie of typeparameterconversie.
  • CS0315: Het type kan niet worden gebruikt als typeparameter T in het generieke type of de methode TypeorMethod<T>. Er is geen boxing conversie.

Als u deze fouten wilt corrigeren, gebruikt u typeargumenten die voldoen aan alle beperkingen via de juiste conversies, zorgt u ervoor dat afgeleide klassen basisklassebeperkingen herhalen en begrijpen dat null-waardetypen speciale beperkingsvereisten hebben:

  • Wijzig het typeargument in een argument met een impliciete verwijzingsconversie naar het beperkingstype (CS0311). Wanneer een typeparameter een beperking heeft zoals where T : BaseType, moet elk typeargument omgezet kunnen worden naar BaseType door een impliciete verwijzingsconversie of identiteitsconversie. Het typeargument moet ofwel BaseType zelf zijn, zijn afgeleid van BaseType, of BaseType implementeren als het een interface is. Impliciete numerieke conversies (zoals van short naar int) voldoen niet aan algemene typeparameterbeperkingen omdat deze conversies waardeconversies zijn, niet verwijzingsconversies.
  • Herhaal de parameterbeperkingen van de basisklasse in eventuele declaraties van afgeleide klassen (CS0314). Wanneer een afgeleide algemene klasse wordt overgenomen van een algemene basisklasse die beperkingen heeft voor de typeparameters, moet de afgeleide klasse dezelfde beperkingen voor de bijbehorende typeparameters declareren. U moet deze beperkingen herhalen omdat de compiler moet controleren of de typeargumenten die zijn opgegeven aan de afgeleide klasse voldoen aan de vereisten van de basisklasse. Als u bijvoorbeeld een klasse hebt public class A<T> where T : SomeClassdie ermee wordt afgeleid, moet deze worden gedeclareerd als public class B<T> : A<T> where T : SomeClass.
  • Gebruik niet-null-waardetypen of wijzig het beperkingstype (CS0312, CS0313). Null-waardetypen (zoals int?) verschillen van de onderliggende waardetypen en voldoen niet aan dezelfde beperkingen. Er is geen impliciete conversie tussen int? en int, en null-waardetypen kunnen niet voldoen aan interfacebeperkingen, omdat de nullable wrapper zelf de interface niet implementeert, ook al is dat wel het onderliggende waardetype. Als u deze fouten wilt oplossen, gebruikt u de niet-nulleerbare vorm van het waardetype als het typeargument, of past u de beperking aan om, indien van toepassing, een nullable verwijzingstype te accepteren.
  • Zorg ervoor dat typeargumenten voldoen aan referentietype- of klassebeperkingen (CS0315). Wanneer een typeparameter is beperkt tot een klassetype (zoals where T : SomeClass), kunt u geen waardetype (struct) gebruiken als het typeargument omdat er geen boksconversie is die voldoet aan de beperkingsrelatie. Voor de beperking is een verwijzingstype vereist dat een overname- of implementatierelatie heeft met het beperkingstype. Als u deze fout wilt oplossen, wijzigt u de struct in een klasse als dit semantisch van toepassing is of verwijdert u de klassebeperking als het algemene type kan werken met waardetypen.

Zie Beperkingen voor typeparameters en impliciete conversies voor meer informatie.

Algemene gebruiksbeperkingen voor generieke typen

De volgende fouten hebben betrekking op beperkingen voor het gebruik van algemene typen:

  • CS0403: Kan null niet converteren naar typeparameter omdat het een niet-null-waardetype kan zijn. Overweeg in plaats daarvan te gebruiken default(T) .
  • CS0413: De typeparameter kan niet worden gebruikt met de as operator omdat deze geen klassetypebeperking of een class beperking heeft.
  • CS0695: Het type kan niet beide interfaces implementeren omdat ze mogelijk verenigd kunnen worden voor bepaalde typeparametervervangingen.
  • CS0698: Een algemeen type kan niet worden afgeleid van het type omdat het een kenmerkklasse is.
  • CS8322: Kan argument met dynamisch type niet doorgeven aan algemene lokale functie met afgeleide typeargumenten.
  • CS9338: Inconsistente toegankelijkheid: type is minder toegankelijk dan klasse.

Als u deze fouten wilt corrigeren, gebruikt default u in plaats van null voor niet-getrainde typeparameters, voegt u klassebeperkingen toe wanneer u de as operator gebruikt, voorkomt u conflicten met interface-eenwording, maakt u geen algemene kenmerkklassen en zorgt u ervoor dat typeargumenten overeenkomen met de zichtbaarheid van de bijbehorende leden:

  • Vervang null toewijzingen door default(T) of voeg een class beperking toe (CS0403). Wanneer u een niet-gekoppelde typeparameter toewijst null , kan de compiler niet garanderen dat het typeargument een verwijzingstype null is dat waarden accepteert, omdat het mogelijk een waardetype is zoals int of struct, wat niet kan zijn null. Als u deze fout wilt oplossen, gebruikt u default(T), dat de juiste standaardwaarde biedt voor elk type (null voor verwijzingstypen, nul of leeg voor waardetypen), of voegt u een class-beperking toe aan de typeparameter als u specifiek de semantiek van verwijs-typen nodig hebt en u wilt toestaan dat null-toewijzingen worden gemaakt.
  • Voeg een class of specifieke typebeperking toe wanneer u de as operator (CS0413) gebruikt. De as operator voert een veilige typecast uit die retourneert null als de conversie mislukt, maar dit gedrag is niet compatibel met waardetypen omdat waardetypen niet kunnen zijn null. Wanneer u een niet-gekoppelde typeparameter gebruikt as , kan de compiler niet garanderen dat het typeargument geen waardetype is, zodat de code wordt geweigerd. Als u deze fout wilt oplossen, voegt u een class beperking of een specifieke referentietypebeperking (zoals where T : SomeClass) toe om ervoor te zorgen dat de typeparameter altijd een verwijzingstype is dat het null resultaat van een mislukte cast correct kan verwerken.
  • Vermijd het implementeren van dezelfde algemene interface meerdere keren met typeparameters die kunnen samenvoegen (CS0695). Wanneer een klasse meerdere keren een algemene interface implementeert met verschillende typeparameters (zoals class G<T1, T2> : I<T1>, I<T2>), bestaat het risico dat iemand deze kan instantiëren met hetzelfde type voor beide parameters (G<int, int>), waardoor er een conflict ontstaat omdat de klasse twee keer zou worden geïmplementeerd I<int> . Als u deze fout wilt oplossen, implementeert u de interface slechts één keer, herstructureert u uw typeparameters om een eenwording te voorkomen of gebruikt u afzonderlijke niet-algemene klassen voor verschillende specialisaties.
  • Algemene typeparameters verwijderen uit kenmerkklassen (CS0698).

    Opmerking

    Deze fout wordt niet geproduceerd in de huidige versies van C#, omdat algemene kenmerken nu worden ondersteund.

  • Geef expliciet typeargumenten op bij het doorgeven van dynamische waarden aan algemene lokale functies (CS8322). Wanneer u een dynamic argument doorgeeft aan een algemene lokale functie, kan de compiler geen typeargumenten afleiden omdat het werkelijke type pas bekend is als runtime. Als u deze fout wilt oplossen, geeft u expliciet het typeargument op (bijvoorbeeld LocalFunc<int>(d)), castt u de dynamische waarde naar het verwachte type of gebruikt u een niet-dynamische variabele.
  • Zorg ervoor dat typeargumenten die worden gebruikt in openbare of beveiligde handtekeningen minstens zo toegankelijk zijn als het lid dat deze gebruikt (CS9338). Een openbaar of beveiligd algemeen lid moet typeargumenten gebruiken die openbaar toegankelijk zijn. Anders kan externe code niet naar behoren verwijzen of de handtekening van het lid gebruiken. Als u bijvoorbeeld een intern type public class Container<T>T hebt, kunnen externe assembly's de Container zien, maar er niet goed mee werken, omdat ze T niet kunnen zien. U kunt deze fout oplossen door het typeargument openbaar te maken of de toegankelijkheid van het lid te verminderen zodat deze overeenkomt met de toegankelijkheid van het typeargument.

Zie Beperkingen voor typeparameters, standaardwaardeexpressies en kenmerken voor meer informatie.

Geldige beperkingstypen

De volgende fouten hebben betrekking op het gebruik van ongeldige typen als beperkingen voor algemene typeparameters:

  • CS0405: Dubbele beperking voor typeparameter.
  • CS0702: Beperking kan geen speciale klasse zijn.
  • CS0703: Inconsistente toegankelijkheid: restrictietype is minder toegankelijk dan de declaratie.
  • CS0706: Ongeldig beperkingstype. Een type dat als beperking wordt gebruikt, moet een interface, een niet-verzegelde klasse of een typeparameter zijn.
  • CS0717: statischestatic class klassen kunnen niet worden gebruikt als beperkingen.

Een beperking moet een interface, een niet-verzegelde klasse of een typeparameter zijn. Bepaalde typen zijn ongeldig als beperkingen vanwege hun speciale betekenis in het .NET-typesysteem of omdat ze niet kunnen worden overgenomen.

Ga als volgt te werk om deze fouten te corrigeren:

  • Dubbele beperkingen verwijderen (CS0405). Elke beperking kan slechts eenmaal worden weergegeven in een beperkingscomponent. Als u where T : I, I hebt, verwijder het duplicaat.
  • Gebruik geen speciale klassen als beperkingen (CS0702). De typen Objecten ArrayValueType kunnen niet als beperkingen worden gebruikt. Elk type is al afgeleid van Object, dus het beperken ervan biedt geen waarde. Array en ValueType abstracte basistypen zijn die niet rechtstreeks kunnen worden overgenomen. Als u gedrag vergelijkbaar met een array nodig hebt, gebruikt u in plaats daarvan IList<T> of IEnumerable<T>.
  • Zorg ervoor dat de beperkingstypen minstens zo toegankelijk zijn als het algemene type (CS0703). Een openbaar algemeen type kan geen beperkingen hebben met behulp van interne typen, omdat externe code geen geldige typeargumenten kan opgeven. Maak het beperkingstype openbaar of verminder de toegankelijkheid van het algemene type.
  • Gebruik alleen interfaces, niet-verzegelde klassen of typeparameters als beperkingen (CS0706). U kunt geen matrices, verzegelde klassen, structs, opsommingen of andere ongeldige typen gebruiken als beperkingen. Als u specifiek gedrag nodig hebt, kunt u overwegen een interface te gebruiken die door de gewenste typen wordt geïmplementeerd.
  • Gebruik geen statische klassen als beperkingen (CS0717). Statische klassen kunnen niet worden uitgebreid omdat ze alleen statische leden bevatten. Er kan geen type bestaan dat is afgeleid van een statische klasse, waardoor het niet meer wordt gebruikt als een beperking. Gebruik in plaats daarvan een niet-statische klasse of interface.

In het volgende voorbeeld ziet u geldige beperkingstypen:

public interface IMyInterface { }
public class MyBaseClass { }

// Valid: interface constraint
class A<T> where T : IMyInterface { }

// Valid: non-sealed class constraint
class B<T> where T : MyBaseClass { }

// Valid: type parameter constraint
class C<T, U> where T : U { }

Zie Beperkingen voor typeparameters voor meer informatie.

Conflicten met beperkingen en kringafhankelijkheden

De volgende fouten hebben betrekking op conflicten tussen beperkingen of kringafhankelijkheden in beperkingsdeclaraties:

  • CS0454: Afhankelijkheid van kringbeperking met typeparameter 1 en typeparameter 2.
  • CS0455: De parameter Type neemt conflicterende beperkingen over.

Beperkingen kunnen geen kringafhankelijkheden maken en typeparameters kunnen geen conflicterende beperkingen overnemen die niet tegelijkertijd kunnen worden voldaan.

Ga als volgt te werk om deze fouten te corrigeren:

  • Kringbeperkingsafhankelijkheden verwijderen (CS0454). Een typeparameter kan niet direct of indirect afhankelijk zijn van zichzelf door de beperkingen. Een voorbeeld hiervan is dat where T : U where U : T een kringafhankelijkheid creëert, omdat T afhankelijk is van U en U afhankelijk is van T. Verbreek de cyclus door een van de beperkingen te verwijderen.
  • Conflicterende overgenomen beperkingen (CS0455) verwijderen. Een typeparameter kan niet worden beperkt tot meerdere niet-gerelateerde klassen, omdat C# geen ondersteuning biedt voor meerdere klassenovername. Op dezelfde manier kan het niet beperkt worden tot zowel struct als een klassetype, omdat deze beperkingen elkaar uitsluiten. Herstructureer uw typehiërarchie of verwijder een van de conflicterende beperkingen.

In het volgende voorbeeld ziet u de problemen:

// CS0454: Circular dependency - T depends on U and U depends on T
class Circular<T, U> where T : U where U : T { }

// CS0455: Conflicting constraints - U can't derive from both B and B2
public class B { }
public class B2 { }
public class G<T> where T : B
{
    public class N<U> where U : B2, T { }
}

Zie Beperkingen voor typeparameters voor meer informatie.

Variantie van parametertype

De volgende fout heeft betrekking op variantieaanpassingen voor algemene typeparameters:

  • CS1961: Ongeldige variantie: de typeparameter moet een geldige variant zijn van het type.

Variantieaanpassingen (in voor contravariantie, out voor covariantie) bepalen hoe u typeparameters gebruikt in interface- en gedelegeerdendeclaraties. Een parameter van het type covariant (out) kan alleen worden weergegeven in uitvoerposities (retourtypen), terwijl een parameter van het type contravariant (in) alleen kan worden weergegeven in invoerposities (parametertypen).

Ga als volgt te werk om deze fout te corrigeren:

  • Gebruik out (covariant) voor typeparameters die alleen worden weergegeven in retourtypen. Met covariantie kan een meer afgeleid type worden gebruikt waarbij een minder afgeleid type wordt verwacht.
  • Gebruik in (contravariant) voor typeparameters die alleen worden weergegeven in parametertypen. Met contravariantie kan een minder afgeleid type worden gebruikt waarbij een meer afgeleid type wordt verwacht.
  • Verwijder de variantieaanpassing als de typeparameter moet worden weergegeven in zowel invoer- als uitvoerposities.

In het volgende voorbeeld ziet u het juiste en onjuiste variantiegebruik:

// Incorrect: out T can't appear in input position
interface IWrong<out T>
{
    void Method(T arg);  // CS1961
}

// Correct: out T only in output positions
interface ICovariant<out T>
{
    T GetValue();
}

// Correct: in T only in input positions
interface IContravariant<in T>
{
    void Process(T arg);
}

// No modifier needed for both input and output
interface IInvariant<T>
{
    T Transform(T arg);
}

Zie Covariantie en Contravariantie in Generics voor meer informatie.