where (genel tür kısıtlaması) (C# Başvurusu)
where
Genel bir tanımdaki yan tümcesi, genel bir tür, yöntem, temsilci veya yerel işlevdeki tür parametreleri için bağımsız değişken olarak kullanılan türlerdeki kısıtlamaları belirtir. Kısıtlamalar arabirimleri, temel sınıfları belirtebilir veya genel bir türün başvuru, değer veya yönetilmeyen tür olmasını gerektirebilir. Tür bağımsız değişkeninin sahip olması gereken özellikleri bildirir ve bildirilen temel sınıf veya uygulanan arabirimlerden sonra yerleştirilmelidir.
Örneğin, tür parametresi arabirimini T
uygulayan IComparable<T> genel bir sınıf AGenericClass
bildirebilirsiniz:
public class AGenericClass<T> where T : IComparable<T> { }
Not
Sorgu ifadesindeki where yan tümcesi hakkında daha fazla bilgi için where yan tümcesine bakın.
Yan tümcesi where
temel sınıf kısıtlaması da içerebilir. Temel sınıf kısıtlaması, bu genel tür için tür bağımsız değişkeni olarak kullanılacak bir türün belirtilen sınıfı temel sınıf olarak veya bu temel sınıf olduğunu belirtir. Temel sınıf kısıtlaması kullanılırsa, bu tür parametresindeki diğer kısıtlamalardan önce görünmelidir. Bazı türlere temel sınıf kısıtlaması olarak izin verilmez: Object, Arrayve ValueType. Aşağıdaki örnekte artık temel sınıf olarak belirtilebilen türler gösterilmektedir:
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 atanabilir bir bağlamda, temel sınıf türünün null atanabilirliği zorlanır. Temel sınıf null atanamazsa (örneğin Base
), tür bağımsız değişkeni null atanamaz olmalıdır. Temel sınıf null atanabilirse (örneğin Base?
), tür bağımsız değişkeni null atanabilir veya null atanamaz başvuru türü olabilir. Temel sınıf null atanamaz olduğunda tür bağımsız değişkeni null atanabilir bir başvuru türüyse derleyici bir uyarı döndürür.
where
yan tümcesi, türün veya class
struct
olduğunu belirtebilir. kısıtlaması struct
, temel sınıf kısıtlaması belirtme gereksinimini System.ValueType
ortadan kaldırır. Türü System.ValueType
temel sınıf kısıtlaması olarak kullanılamaz. Aşağıdaki örnekte hem hem struct
de class
kısıtlamaları gösterilmektedir:
class MyClass<T, U>
where T : class
where U : struct
{ }
Null atanabilir bir bağlamda kısıtlama, bir türün class
null atanamaz bir başvuru türü olmasını gerektirir. Null atanabilir başvuru türlerine izin vermek için, hem null atanabilir hem de null atanamayan başvuru türlerine izin veren kısıtlamasını kullanın class?
.
where
yan tümcesi kısıtlamayı notnull
içerebilir. kısıtlama, notnull
tür parametresini null atanamayan türlere sınırlar. Tür bir değer türü veya boş değer atanamayan bir başvuru türü olabilir. Kısıtlama notnull
, bir nullable enable
bağlamda derlenen kod için kullanılabilir. Diğer kısıtlamaların aksine, bir tür bağımsız değişkeni kısıtlamayı notnull
ihlal ederse, derleyici hata yerine bir uyarı oluşturur. Uyarılar yalnızca bir nullable enable
bağlamda oluşturulur.
Boş değer atanabilir başvuru türlerinin eklenmesi, genel yöntemlerin T?
anlamı açısından olası bir belirsizlik oluşturur. ise T
struct
ile T?
aynıdır System.Nullable<T>. Ancak, bir başvuru türü ise T
, T?
bunun geçerli bir değer olduğu null
anlamına gelir. Geçersiz kılma yöntemleri kısıtlamaları içeremediğinden belirsizlik ortaya çıkar. Yeni default
kısıtlama bu belirsizliği giderir. Bir temel sınıf veya arabirim bir yöntemin iki aşırı yüklemesini bildirdiğinde bunu eklersiniz; biri kısıtlamayı struct
belirtir ve diğeri veya class
kısıtlaması struct
uygulanmaz:
public abstract class B
{
public void M<T>(T? item) where T : struct { }
public abstract void M<T>(T? item);
}
Türetilmiş sınıfınızın, türetilmiş sınıfınızda veya açık arabirim uygulamanızda kısıtlama olmadan yöntemini geçersiz kılacağını belirtmek için kısıtlamayı kullanırsınız default
. Yalnızca temel yöntemleri veya açık arabirim uygulamalarını geçersiz kılan yöntemlerde geçerlidir:
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 { }
}
Önemli
Kısıtlamayı notnull
içeren genel bildirimler null atanabilir bir belirsiz bağlamda kullanılabilir, ancak derleyici kısıtlamayı zorlamaz.
#nullable enable
class NotNullContainer<T>
where T : notnull
{
}
#nullable restore
Yan where
tümcesi bir unmanaged
kısıtlama da içerebilir. kısıtlama, unmanaged
tür parametresini yönetilmeyen türler olarak bilinen türlere sınırlar. Kısıtlama, unmanaged
C# dilinde alt düzey birlikte çalışma kodu yazmayı kolaylaştırır. Bu kısıtlama, tüm yönetilmeyen türlerde yeniden kullanılabilir yordamları etkinleştirir. Kısıtlama unmanaged
veya struct
kısıtlamasıyla class
birleştirilemiyor. Kısıtlama, unmanaged
türün bir struct
olması gerektiğini zorlar:
class UnManagedWrapper<T>
where T : unmanaged
{ }
Yan tümcesi where
bir oluşturucu kısıtlaması da içerebilir: new()
. Bu kısıtlama işlecini kullanarak new
bir tür parametresi örneği oluşturmayı mümkün kılar. new() Kısıtlaması, derleyicinin sağlanan herhangi bir tür bağımsız değişkeninin erişilebilir bir parametresiz oluşturucuya sahip olması gerektiğini bilmesini sağlar. Örneğin:
public class MyGenericClass<T> where T : IComparable<T>, new()
{
// The following line is not possible without new() constraint:
T item = new T();
}
Kısıtlama new()
, kısıtlamayı önleme tarafından where
takip edilmediği sürece yan tümcesinde allows ref struct
en son görünür. Kısıtlama new()
veya unmanaged
kısıtlamalarıyla struct
birleştirilemiyor. Bu kısıtlamaları karşılayan tüm türlerin erişilebilir bir parametresiz oluşturucuya sahip olması gerekir ve bu da kısıtlamayı new()
yedekli hale getirir.
Bu kısıtlama önleme, için T
tür bağımsız değişkeninin bir ref struct
tür olabileceğini bildirir. Örneğin:
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)
{
}
}
Genel tür veya yöntem, herhangi bir örneği T
için başvuru güvenlik kurallarına uymalıdır çünkü bu bir ref struct
olabilir. allows ref struct
yan tümcesi veya class?
kısıtlamasıyla class
birleştirilemiyor. Kısıtlama önleme, allows ref struct
bu tür bağımsız değişkeni için tüm kısıtlamaları izlemelidir.
Birden çok tür parametresiyle, her tür parametresi için bir where
yan tümce kullanın, örneğin:
public interface IMyInterface { }
namespace CodeExample
{
class Dictionary<TKey, TVal>
where TKey : IComparable<TKey>
where TVal : IMyInterface
{
public void Add(TKey key, TVal val) { }
}
}
Aşağıdaki örnekte gösterildiği gibi, genel yöntemlerin tür parametrelerine kısıtlamalar da ekleyebilirsiniz:
public void MyMethod<T>(T t) where T : IMyInterface { }
Temsilcilerde tür parametresi kısıtlamalarını açıklamak için kullanılan söz diziminin yöntemlerin söz dizimleriyle aynı olduğuna dikkat edin:
delegate T MyDelegate<T>() where T : new();
Genel temsilciler hakkında bilgi için bkz . Genel Temsilciler.
Kısıtlamaların söz dizimi ve kullanımıyla ilgili ayrıntılar için bkz . Tür Parametrelerindeki Kısıtlamalar.
C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.