C # 'da System.Type ve System.RuntimeType arasındaki fark nedir?


90

Bugün bazı konvansiyon testleri yapmaya çalışıyordum ve bir Assembly.GetTypes()şeye rastladığımda (arayarak ) bir montajdaki tüm türleri elde etmeye çalışıyordum :

System.RuntimeType:[First.Namespace.FirstClass]

Ne zaman bu türle karşılaştırmaya çalışsam typeof(FirstClass), eşit değiller. Yani, FirstClassgenel bir parametre olarak içeren tüm türleri bulmaya çalıştığımda , hiçbirini bulamıyorum.

Arasındaki fark nedir System.RuntimeTypeve System.Type?

Sorunumu çözmenin bir yolu var mı?


6
Yaşadığınız sorunu gösteren küçük bir program sağlayabilir misiniz?
Eric Lippert

Ben giderken ise zaten cevabı var edilmiştir: P
Edgar Gonzalez

Yanıtlar:


109

System.RuntimeTypesoyut temel sınıftan türetilen somut bir sınıftır System.Type. Yana System.RuntimeTypegenel değil, genellikle olduğu gibi bunun örneklerini karşılaşacak System.Type.

Bir nesnenin türünü almaya çalıştığınızda ve yanlışlıkla GetType()o nesneyi doğrudan kullanmak yerine, yanlışlıkla ilk nesnenin türünü temsil eden başka bir nesneyi çağırdığınızda kafa karışıklığı ortaya çıkabilir . Ardından çağrıldığı nesne bir Tipi temsil ettiğinde Type.ToString()geri dönecektir "System.RuntimeType":

string str = string.Empty;
Type strType = str.GetType();
Type strTypeType = strType.GetType();
strType.ToString();     // returns "System.string"
strTypeType.ToString(); // returns "System.RuntimeType"

Örneğin, bu blog gönderisinde birisi veritabanındaki bir sütunun türünü almaya çalışıyor ve şöyle bir şey yapıyor:

object val = reader.GetFieldType(index);
Type runtimeType = val.GetType();
PropertyInfo propInfo = runtimeType.GetProperty("UnderlyingSystemType");
Type type = (Type)propInfo.GetValue(val, null);

Val zaten bir Type nesnesi olduğundan, val.GetType () System.RuntimeTime, orijinal tür nesnesini temsil etmek için kullanılan somut tür olduğundan türü temsil eden başka bir Type nesnesi döndürür . Blog gönderisi daha sonra, gerçekten gerekli olan tek şey şuyken, orijinal tip nesnesinin türünü elde etmek için bazı gereksiz yansıma hileleri gösterir:

Type type = reader.GetFieldType(index) as Type;

Dolayısıyla, Typenesneniz a'yı temsil ettiğini bildiriyorsa, önceden sahip olduğunuz bir türü System.RuntimeTypeyanlışlıkla aramadığınızdan emin olun GetType().


İlk kod parçacığı yalnızca nesnenin bir örneği olup olmadığını kontrol eder — Typegeçseniz bile doğru döndürür typeof(int). İkinci kod parçacığı typeof(string).GetType()ve karşılaştırması için çalışmaz typeof(Type).
Mark Cidade

Bu tam olarak aradığım şey! Thomas Danecker'in gönderisini buldum ama Doogal Bell'in gönderisini bulamadım
Edgar Gonzalez

1
@Mark Cidade. İyi tespit, teşekkürler. Daha yararlı olması için sabit cevabım var, umarım bu blog gönderisine atıfta bulunarak ortaya çıkardığım karışıklıkları gideririm.
Ergwun

@Edgar Gonzalez: Referans verdiğim blog yazısı aslında oldukça yanıltıcıydı. Daha iyi bilgi için lütfen güncellenmiş cevabıma bakın.
Ergwun

4

Cevabını itibaren System.Type ve System.RuntimeType arasındaki Farklı tarafından Thomas Danecker :

System.Type, soyut bir temel sınıftır. CLR, System.RuntimeType dahili tipinde somut bir uygulamaya sahiptir. Bu typeof (string) nedeniyle. GetType () bir RuntimeType döndürür ancak typeof (Type) normal bir Type döndürür. .Equals yöntemini kullanmak aslında false döndüren bir object.ReferenceEquals yapar. Beklenen sonuçları elde etmek için type.IsInstanceOfType (element) kullanabilirsiniz. Bu, öğe türetilmiş türde ise true değerini de döndürür. Tam türü kontrol etmek isterseniz, yönteminizin yanlış dönüş değeri istenen sonuçtur. RuntimeType'ı kontrol etmek için checkType (arrayType, Type.GetType ("System.RuntimeType")) da kullanabilirsiniz.


1
"aslında bir" - Bir dilbilgisi düzeltmesi alabilir miyiz? Bu, her şeyin özü gibi ve mantıklı değil.
N73k

2

Kısaca...

    "".GetType().ToString()           == "System.String"

    "".GetType().GetType().ToString() == "System.RuntimeType"

Şimdi düşündüğüm şekilde System.Type, çalışma zamanında nesne türü istek sonuçlarını temsil eden tür için temel bir tür, yani System.RuntimeType. Dolayısıyla, içinde olduğu gibi bir nesnenin türünü talep ettiğinizde "".GetType(), System.Typedönen örneği onun alt öğesidir System.RuntimeType. Aslında, birinin de olması gerektiğini beklemek typeof(System.Type).GetType()gerekir System.RuntimeType, ancak bence çerçeve özellikle bunu engelliyor ... simetri.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.