Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Az where általános definíció záradéka a típusparaméterek argumentumaként használt típusokra vonatkozó korlátozásokat határozza meg egy általános típusban, metódusban, delegálásban vagy helyi függvényben. A korlátozások megadhatnak interfészeket, alaposztályokat, vagy megkövetelhetik, hogy egy általános típus hivatkozás, érték vagy nem felügyelt típus legyen. Deklarálják azokat a képességeket, amelyekkel a típusargumentumnak rendelkeznie kell, és minden deklarált alaposztály vagy implementált illesztő után kell elhelyezni.
Deklarálhat például egy általános osztályt, AGenericClasshogy a típusparaméter T implementálja az interfészt IComparable<T> :
public class AGenericClass<T> where T : IComparable<T> { }
Feljegyzés
A lekérdezési kifejezés hol található záradékával kapcsolatos további információkért tekintse meg a hol található záradékot.
A where záradék alaposztály-korlátozást is tartalmazhat. Az alaposztály-korlátozás azt állítja, hogy az adott általános típus típusargumentumaként használandó típus a megadott osztályt alaposztályként vagy alaposztályként használja. Ha az alaposztály-kényszert használja, annak az adott típusparaméterre vonatkozó egyéb megkötések előtt kell megjelennie. Egyes típusok nem engedélyezettek alaposztály-korlátozásként: Object, Arrayés ValueType. Az alábbi példa az alaposztályként megadható típusokat mutatja be:
public class UsingEnum<T> where T : System.Enum { }
public class UsingDelegate<T> where T : System.Delegate { }
public class Multicaster<T> where T : System.MulticastDelegate { }
Null értékű környezetben a rendszer kikényszeríti az alaposztálytípus nullságát. Ha az alaposztály nem null értékű (például Base), a típusargumentumnak nem null értékűnek kell lennie. Ha az alaposztály null értékű (például Base?), a típusargumentum lehet null értékű vagy nem null értékű hivatkozástípus. A fordító figyelmeztetést ad ki, ha a típusargumentum null értékű hivatkozástípus, ha az alaposztály nem null értékű.
A where záradék megadhatja, hogy a típus egy class vagy egy struct. A struct kényszer nem szükséges megadni egy alaposztály-korlátozást.System.ValueType A System.ValueType típus nem használható alaposztály-korlátozásként. Az alábbi példában a korlátozások és class a struct korlátozások is láthatók:
class MyClass<T, U>
where T : class
where U : struct
{ }
Null értékű környezetben a class kényszer megköveteli, hogy egy típus ne null értékű hivatkozástípus legyen. A null értékű hivatkozástípusok engedélyezéséhez használja a class? kényszert, amely lehetővé teszi a null értékű és a nem null értékű hivatkozástípusokat is.
A where záradék tartalmazhatja a kényszert notnull . A notnull kényszer a típusparamétert nem null értékű típusokra korlátozza. A típus lehet értéktípus vagy nem null értékű hivatkozástípus. A notnull kényszer elérhető a környezetbennullable enable. A többi kényszertől eltérően, ha egy típusargumentum megsérti a notnull kényszert, a fordító hibaüzenet helyett figyelmeztetést hoz létre. A figyelmeztetések csak egy nullable enable környezetben jönnek létre.
A null értékű referenciatípusok hozzáadása potenciális kétértelműséget vezet be az általános módszerek jelentésében T? . Ha T egy struct, akkor ugyanaz, T? mint System.Nullable<T>a . Ha T azonban hivatkozástípusról van szó, az azt jelenti, T? hogy null érvényes érték. A kétértelműség azért merül fel, mert a felülíró metódusok nem tartalmazhatnak korlátozásokat. Az új default korlátozás feloldja ezt a kétértelműséget. Akkor adja hozzá, ha egy alaposztály vagy felület egy metódus két túlterhelését deklarálja, egyet, amely megadja a struct kényszert, és egyet, amely nem alkalmazza a vagy a structclass kényszert:
public abstract class B
{
public void M<T>(T? item) where T : struct { }
public abstract void M<T>(T? item);
}
A kényszer használatával default megadhatja, hogy a származtatott osztály felülbírálja a metódust a származtatott osztály kényszere vagy explicit felületi implementáció nélkül. Csak az alap metódusokat felülbíráló metódusokra vagy explicit felületi implementációkra érvényes:
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 { }
}
Fontos
A kényszert tartalmazó notnull általános deklarációk null értékű, oblivious környezetben használhatók, a fordító azonban nem kényszeríti ki a kényszert.
#nullable enable
class NotNullContainer<T>
where T : notnull
{
}
#nullable restore
A where záradék korlátozást unmanaged is tartalmazhat. A unmanaged korlátozás a típusparamétert nem felügyelt típusokra korlátozza. A unmanaged korlátozás megkönnyíti az alacsony szintű interop kód írását C#-ban. Ez a korlátozás minden nem felügyelt típus esetében lehetővé teszi az újrahasználható rutinokat. A unmanaged kényszer nem kombinálható a korlátozással vagy class a struct korlátozással. A unmanaged kényszer kikényszeríti, hogy a típusnak a következőnek kell lennie struct:
class UnManagedWrapper<T>
where T : unmanaged
{ }
A where záradék konstruktor-kényszert is tartalmazhat. new() Ez a korlátozás lehetővé teszi egy típusparaméter példányának létrehozását az new operátor használatával. Az új() korlátozás tudatja a fordítóval, hogy a megadott típusargumentumoknak elérhető paraméter nélküli konstruktorsal kell rendelkezniük. Példa:
public class MyGenericClass<T> where T : IComparable<T>, new()
{
// The following line is not possible without new() constraint:
T item = new T();
}
A new() kényszer utolsóként jelenik meg a where záradékban, hacsak nem követi az allows ref struct anti-kényszer. A new() kényszer nem kombinálható a korlátozásokkal vagy struct a unmanaged korlátozásokkal. A kényszernek megfelelő összes típusnak elérhető paraméter nélküli konstruktorsal kell rendelkeznie, így a new() kényszer redundánssá válik.
Ez az anti-korlátozás azt deklarálja, hogy a típus argumentuma T lehet típus ref struct . Példa:
public class GenericRefStruct<T> where T : allows ref struct
{
// Scoped is allowed because T might be a ref struct
public void M(scoped T parm)
{
}
}
Az általános típusnak vagy metódusnak minden példányra be kell tartania T a ref biztonsági szabályokat, mert lehet, hogy egy ref struct. A allows ref struct záradék nem kombinálható a korlátozással vagy class a class? korlátozással. Az allows ref struct anti-kényszernek az adott típusargumentum összes kényszerét követnie kell.
Több típusparaméter esetén minden típusparaméterhez használjon egy where záradékot, például:
public interface IMyInterface { }
namespace CodeExample
{
class Dictionary<TKey, TVal>
where TKey : IComparable<TKey>
where TVal : IMyInterface
{
public void Add(TKey key, TVal val) { }
}
}
Az általános metódusok típusparamétereihez kényszereket is csatolhat, ahogyan az alábbi példában látható:
public void MyMethod<T>(T t) where T : IMyInterface { }
Figyelje meg, hogy a delegáltak típusparaméter-korlátozásait leíró szintaxis megegyezik a metódusok szintaxisával:
delegate T MyDelegate<T>() where T : new();
Az általános meghatalmazottakról további információt az Általános meghatalmazottak című témakörben talál.
A kényszerek szintaxisával és használatával kapcsolatos részletekért tekintse meg a típusparaméterekre vonatkozó korlátozásokat.
C# nyelvspecifikáció
További információkért lásd a C# nyelvi specifikációját. A nyelvi specifikáció a C#-szintaxis és -használat végleges forrása.