Bu sorunu ayrıntılı olarak açıklayan bir Microsoft Connect makalesi bulabildim :
Ne yazık ki, bu davranış tasarım gereğidir ve değer türlerini içerebilecek tür parametreleriyle kullanımının kolay bir çözümü yoktur.
Türlerin referans türleri olduğu biliniyorsa, nesne kendi özel aşırı yüklenmesini belirtebilse de, nesne üzerinde tanımlanan varsayılan aşırı yük, referans eşitliğini test eder. Derleyici, değişkenin statik tipine göre hangi aşırı yüklenmenin kullanılacağını belirler (belirleme polimorfik değildir). Bu nedenle, genel tip parametresi T'yi mühürlü olmayan bir başvuru tipiyle (İstisna gibi) sınırlamak için örneğinizi değiştirirseniz, derleyici kullanılacak belirli aşırı yükü belirleyebilir ve aşağıdaki kod derlenir:
public class Test<T> where T : Exception
Türlerin değer türleri olduğu biliniyorsa, kullanılan kesin türlere göre belirli değer eşitliği testleri gerçekleştirir. Referans karşılaştırmaları değer türleri üzerinde anlamlı olmadığından ve derleyici hangi belirli değer karşılaştırmasının yayılacağını bilemediğinden burada iyi bir "varsayılan" karşılaştırma yoktur. Derleyici ValueType.Equals (Object) çağrısı yayabilir, ancak bu yöntem yansıma kullanır ve belirli değer karşılaştırmalarına kıyasla oldukça verimsizdir. Bu nedenle, T'de bir değer türü kısıtlaması belirtmiş olsanız bile, derleyicinin burada oluşturması için makul bir şey yoktur:
public class Test<T> where T : struct
Derleyicinin T'nin bir değer mi, yoksa referans tipi mi olduğunu bile bilmediği durumlarda, benzer şekilde üretilecek tüm olası tipler için geçerli olacak hiçbir şey yoktur. Referans karşılaştırması değer türleri için geçerli olmaz ve aşırı yüklenmeyen referans türleri için bir tür değer karşılaştırması beklenmez.
İşte yapabilecekleriniz ...
Bu yöntemlerin her ikisinin de referans ve değer türlerinin genel bir karşılaştırması için çalıştığını doğruladım:
object.Equals(param, default(T))
veya
EqualityComparer<T>.Default.Equals(param, default(T))
"==" işleci ile karşılaştırma yapmak için şu yöntemlerden birini kullanmanız gerekir:
Tüm T vakaları bilinen bir temel sınıftan türüyorsa, derleyiciye genel tür kısıtlamaları kullanarak bilgi verebilirsiniz.
public void MyMethod<T>(T myArgument) where T : MyBase
Derleyici daha sonra işlemlerin nasıl yapılacağını tanır MyBase
ve şu anda gördüğünüz "T" ve "T" türündeki işlemcilere "Operator '==" uygulanamaz.
Başka bir seçenek de T'yi uygulayan herhangi bir türle kısıtlamak olacaktır IComparable
.
public void MyMethod<T>(T myArgument) where T : IComparable
Ve sonra IComparable arabirimiCompareTo
tarafından tanımlanan yöntemi kullanın .
if (myArgument?.Equals( default(T) ) != null )
.