2011-12-18 13 views
18

böyle bir şeydir:C# Yansıma: Nullable <int> türünü nasıl edinebilirim? Yapmak istediğim ne

switch(myObject.GetType().GetProperty("id")) 
{ 
    case ??: 
     // when Nullable<Int32>, do this 
    case ??: 
     // when string, do this 
    case ??: 
     // when Nullable<bool>, do this 

object.GetType altında ne yol() Bir vaka ifadesini kullanarak karşılaştırabilirsiniz veri türü dize adı var ki? Ben türünü bilmek gerekir, bu yüzden Reflection kullanarak myObject değerini ayarlayacak birçok Convert.ToInt32 (string) birine sahip olabilirsiniz.

+1

Bu neredeyse kesinlikle yanlış şeyler yapıyor. Neden dev bir anahtar ifadesi kullanmak yerine polimorfizmden yararlanamıyorsunuz? –

+0

Farklı parametre türleri ile çeşitli işlevler oluşturmanızı önerebilirseniz, yapabilirim. Bu durumda, bir nesneden diğerine her zaman bir dize türü olan farklı türdeki bir özellik kümesini kopyalıyorum. Yani, atamak için değeri dönüştürmem gerekiyor. Bu ve Reflection ile çok az deneyimim var. –

+0

@CodyGray yansımasıyla ilgili bir şeyler yapıyor olabilir, kendi ORM'sini yazmayı söyleyin. Ya da tüm bu DAO'lar için özel bir serileştirici yazarken asla bilemezsiniz. – nawfal

cevap

8

Güncelleştirme: C# 7 bu sorunun yanıtını almaya çalıştığı için Type s geçişini destekleyecektir. Bu biraz farklı olsa da, sözdizimi kara mayınlarına dikkat edin.

Bunu karşılaştırmak için bir dize isim gerek yoktur:

if (myObject.GetType().GetProperty("id").PropertyType == typeof(Nullable<Int32>)) 
    // when Nullable<Int32>, do this 
else if (myObject.GetType().GetProperty("id").PropertyType == typeof(string)) 
    // when string, do this 
else if (myObject.GetType().GetProperty("id").PropertyType == typeof(Nullable<bool>)) 
    // when Nullable<bool>, do this 
+1

.GetType() to typeof (Nullable ) ile karşılaştırdığınızdan emin misiniz, yoksa GetType() altında bir özellik mi? Int varsayarsak? ve Nullable aynı türdür, a.GetType()! = typeof (Nullable ). –

+0

Muhtemelen bir 'switch' ifadesi yerine' if' ifadeleri ile bunu yapmak zorundasınız. Ama senin gibi, bunu daha önce hiç yapmadım. Bana bir anti-desen gibi görünüyor. –

+0

VS Stüdyosu, yukarıdaki kod anahtarı üzerinden panik atak geçirecektir (myObject.GetType()) "Integral tipinin beklenen değeri" şeklinde bir IDE hatası gösterecektir ve case typeof (XXX), "Sabit Değer bekleniyor" şeklindeki bir IDE hatasını gösterecektir. – heads5150

0

@Cody Gri söylediği gibi ifadeleri muhtemelen aşağıdaki kullanıyorum iyi yolu

var t = myObject.GetType(); 

if (t == typeof(Nullable<int>)) 
{ } 
else if (t == typeof(string)) 
{} 
else if (t==typeof(Nullable<bool>)) 
{} 
+2

ilginç, yeterli? a = 3' sonra 'typeof (a)' dır "System.Int32" –

+1

@ Dr.Zim: Burada açıklamaya bakın: http://stackoverflow.com/questions/785358/nullable-type-is-not-a-nullable -Type –

+1

@ Dr.Zim typeof (a) 'bile derleme değil. 'Int' döndüren bir .GetType()' dır. – CodesInChaos

44

olurdu türün nullable olup olmadığını ve gerçek türünü almak için kullanılacak kod türü:

if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) 
{ 
    return Nullable.GetUnderlyingType(type); 
} 

NULLLAble bu kod int bölümünü (alttaki tür) döndürür. Nesneyi belirli bir türe dönüştürmeniz gerekiyorsa, System.Convert.ChangeType yöntemini kullanabilirsiniz.

+0

+1 olarak bildirilirse ve intranın aynı tipte olup olmadığını belirttikten sonra int türünü verir. Nullable <>) 'dır, bundan sonra null bir kontrol yaptıktan sonra if ifadesi yerine de çalışırdı. – Connell

16

Soru çok kafa karıştırıcı. "MyObject" nulu bir int olabilecek nesne mi? Yoksa "NULL" türü null türündeki int türünde mi? Birincisi, sorunuz bir yanlışlık gerektirdiği için cevaplanamaz. Kutulu nullable int diye bir şey yoktur. Bu nedenle, if (myobject.GetType() == typeof(int?)) öneren tüm cevapların yanlış olduğunu unutmayın; Durum asla gerçek olmayacak.

Niçin bir int nesnelere dönüştürdüğünüzde, ya boş bir referans olur (eğer null olmayan int değeri yoksa) ya da kutulu bir int olur. Hiçbir nesneyi null olan bir int içerip içermediğini belirlemek için bir yol yoktur, çünkü hiçbir zaman hiçbir null olmayan int içerir.

İkincisindeyse özelliği değerini typeof(int?) ile karşılaştırın. Bir anahtar kullanamazsınız; Anahtarlar için sadece sabitler kullanılabilir ve tipler sabit değildir.

Bütün bunlar, bu kötü bir kod kokusu. Neden ilk etapta yansıma kullanıyorsunuz?

+0

Güncelleme: C# 7'de, anahtar ifadeleri artık sabit ifadeler gerektirmez. –

+0

Ve türleri açmaya yönelik bir mekanizma sağlar. Bu özellik ilk olarak 2001'de mi önerildi? Bence. Yani, 16 yıl, fena değil. –

2

. Net'de, değer türlerinin örnekleri, ilişkili tür bilgisi olmayan, yalnızca bitlerin koleksiyonlarıdır. Ancak, Nullable<T> dışındaki her değer türü için, sistem ayrıca System.ValueType'dan türeyen karşılık gelen bir sınıf türünü otomatik olarak oluşturur. Değer türünden otomatik oluşturulan sınıf türüne ve otomatik oluşturulan sınıf türünden değer türüne göre daraltma dönüşümünden oluşan bir genişletme dönüşümü vardır. Nullable<T> söz konusu olduğunda, değer türüne/dönüşümden elde edilen karşılık gelen otomatik olarak oluşturulan sınıf türü yoktur; bunun yerine, genişleyen dönüşümler Nullable<T> ve T ile ilişkili sınıf türünde her iki yönde de vardır.

Anlatabildiğim kadarıyla, bu garip davranış, null ve boş bir Nullable<T> arasındaki karşılaştırmaları doğru olarak döndürmek için uygulandı.