Delen via


where (generic type constraint) (C#-verwijzing)

De where component in een algemene definitie geeft beperkingen op voor de typen die worden gebruikt als argumenten voor typeparameters in een algemeen type, methode, gemachtigde of lokale functie. Beperkingen kunnen interfaces, basisklassen opgeven of vereisen dat een algemeen type een verwijzing, waarde of onbeheerd type is. Ze declareren mogelijkheden die het typeargument moet hebben en moeten worden geplaatst na een gedeclareerde basisklasse of geïmplementeerde interfaces.

U kunt bijvoorbeeld een algemene klasse declareren, AGenericClasszodat de typeparameter T de IComparable<T> interface implementeert:

public class AGenericClass<T> where T : IComparable<T> { }

Notitie

Zie waar de component is voor meer informatie over de where-component in een query-expressie.

De where component kan ook een basisklassebeperking bevatten. De beperking basisklasse geeft aan dat een type dat moet worden gebruikt als een typeargument voor dat algemene type de opgegeven klasse als basisklasse heeft, of dat is die basisklasse. Als de beperking van de basisklasse wordt gebruikt, moet deze worden weergegeven vóór andere beperkingen voor die typeparameter. Sommige typen zijn niet toegestaan als basisklassebeperking: Object, Arrayen ValueType. In het volgende voorbeeld ziet u de typen die nu kunnen worden opgegeven als basisklasse:

public class UsingEnum<T> where T : System.Enum { }

public class UsingDelegate<T> where T : System.Delegate { }

public class Multicaster<T> where T : System.MulticastDelegate { }

In een null-context wordt de null-waarde van het type basisklasse afgedwongen. Als de basisklasse niet null kan worden gebruikt (bijvoorbeeld Base), moet het typeargument niet null zijn. Als de basisklasse null kan worden gebruikt (bijvoorbeeld Base?), kan het typeargument een nullable of niet-nullable verwijzingstype zijn. De compiler geeft een waarschuwing uit als het typeargument een null-verwijzingstype is wanneer de basisklasse niet nullbaar is.

De where component kan opgeven dat het type een class of een structis. De struct beperking verwijdert de noodzaak om een basisklassebeperking van System.ValueType. Het System.ValueType type kan niet worden gebruikt als basisklassebeperking. In het volgende voorbeeld ziet u zowel de beperkingen als struct de class beperkingen:

class MyClass<T, U>
    where T : class
    where U : struct
{ }

In een null-context vereist de class beperking dat een type een niet-null-verwijzingstype is. Als u null-verwijzingstypen wilt toestaan, gebruikt u de class? beperking, waarmee zowel nullable als niet-nullable verwijzingstypen zijn toegestaan.

De where component kan de notnull beperking bevatten. De notnull beperking beperkt de typeparameter tot niet-nullable typen. Het type kan een waardetype of een niet-null-verwijzingstype zijn. De notnull beperking is beschikbaar voor code die in een nullable enable context is gecompileerd. In tegenstelling tot andere beperkingen, als een typeargument de notnull beperking schendt, genereert de compiler een waarschuwing in plaats van een fout. Waarschuwingen worden alleen gegenereerd in een nullable enable context.

De toevoeging van null-referentietypen introduceert een mogelijke dubbelzinnigheid in de betekenis van T? algemene methoden. Als T het een struct, T? is hetzelfde als System.Nullable<T>. Als T dit echter een verwijzingstype is, T? betekent dit een null geldige waarde. De dubbelzinnigheid ontstaat omdat het overschrijven van methoden geen beperkingen kan bevatten. Met de nieuwe default beperking wordt deze dubbelzinnigheid opgelost. U voegt deze toe wanneer een basisklasse of -interface twee overbelastingen van een methode declareert, een die de struct beperking aangeeft en een die niet de of class beperking struct heeft toegepast:

public abstract class B
{
    public void M<T>(T? item) where T : struct { }
    public abstract void M<T>(T? item);

}

U gebruikt de default beperking om op te geven dat de afgeleide klasse de methode overschrijft zonder de beperking in uw afgeleide klasse of expliciete interface-implementatie. Dit is alleen geldig voor methoden die basismethoden overschrijven of expliciete interface-implementaties:

public class D : B
{
    // Without the "default" constraint, the compiler tries to override the first method in B
    public override void M<T>(T? item) where T : default { }
}

Belangrijk

Algemene declaraties die de notnull beperking bevatten, kunnen worden gebruikt in een lege context, maar compiler dwingt de beperking niet af.

#nullable enable
    class NotNullContainer<T>
        where T : notnull
    {
    }
#nullable restore

De where component kan ook een unmanaged beperking bevatten. De unmanaged beperking beperkt de typeparameter tot typen die niet-beheerde typen worden genoemd. Met unmanaged deze beperking kunt u eenvoudiger interopcode op laag niveau schrijven in C#. Deze beperking maakt herbruikbare routines mogelijk voor alle niet-beheerde typen. De unmanaged beperking kan niet worden gecombineerd met de class of struct beperking. De unmanaged beperking dwingt af dat het type een struct:

class UnManagedWrapper<T>
    where T : unmanaged
{ }

De where component kan ook een constructorbeperking bevatten, new(). Met deze beperking kunt u een exemplaar van een typeparameter maken met behulp van de new operator. De nieuwe() beperking laat de compiler weten dat elk opgegeven typeargument een toegankelijke parameterloze constructor moet hebben. Voorbeeld:

public class MyGenericClass<T> where T : IComparable<T>, new()
{
    // The following line is not possible without new() constraint:
    T item = new T();
}

De new() beperking wordt als laatste weergegeven in de where component. De new() beperking kan niet worden gecombineerd met de struct of unmanaged beperkingen. Alle typen die aan deze beperkingen voldoen, moeten een toegankelijke parameterloze constructor hebben, waardoor de new() beperking overbodig wordt.

Gebruik bij meerdere typeparameters één where component voor elke typeparameter, bijvoorbeeld:

public interface IMyInterface { }

namespace CodeExample
{
    class Dictionary<TKey, TVal>
        where TKey : IComparable<TKey>
        where TVal : IMyInterface
    {
        public void Add(TKey key, TVal val) { }
    }
}

U kunt ook beperkingen koppelen aan typeparameters van algemene methoden, zoals wordt weergegeven in het volgende voorbeeld:

public void MyMethod<T>(T t) where T : IMyInterface { }

U ziet dat de syntaxis voor het beschrijven van parameterbeperkingen voor gemachtigden hetzelfde is als die van methoden:

delegate T MyDelegate<T>() where T : new();

Zie Algemene gemachtigden voor informatie over algemene gemachtigden.

Zie Beperkingen voor typeparameters voor meer informatie over de syntaxis en het gebruik van beperkingen.

C#-taalspecificatie

Zie de C#-taalspecificatie voor meer informatie. De taalspecificatie is de definitieve bron voor de C#-syntaxis en het gebruik.

Zie ook