2008-09-18 10 views
21

Bu işi nasıl yapabilirim? türleri için karşılaştıran dize sadece awfull ve değişime tabi olabilir çünküÜzerinde geçiş yapma PropertyType

switch(property.PropertyType){ 
    case typeof(Boolean): 
     //doStuff 
     break; 
    case typeof(String): 
     //doOtherStuff 
     break; 
    default: break; 
} 

Ben adı kullanmak istemiyoruz.

cevap

36
 System.Type propertyType = typeof(Boolean); 
     System.TypeCode typeCode = Type.GetTypeCode(propertyType); 
     switch (typeCode) 
     { 
      case TypeCode.Boolean: 
       //doStuff 
       break; 
      case TypeCode.String: 
       //doOtherStuff 
       break; 
      default: break; 
     } 

Sen TypeCode.Object için bir hibrit yaklaşımı kullanabilirsiniz:/else desen/eğer

if(property.PropertyType == typeof(bool)) { 
    //dostuff; 
} 
else if (property.PropertyType == typeof(string)) { 
    //do other stuff; 
} 
+3

Basit yerleşik türlerden başka bir şeyle karşılaştırmak istiyorsanız çalışmayacaktır, çünkü TypeCode bool, int32 vb gibi basit tiplerde bir şey kaplamaz bir numaralandırmadır ... –

+0

Elbette bu doğrudur. Ama ilk etapta verdiğim örnekte kapsam dışı kalmak. Bu noktayı açıklığa kavuşturmak için daha sonra eklendi. Teşekkürler. –

+0

Eh, benim durumumda sadece baz türleri olacak. –

0

Bir anahtar içinde dizeleri kullanma hakkında endişelenmeyin, çünkü derleyiciniz birkaç kez otomatik olarak onu oldukça iyi görünmesine rağmen iyi bir performans veren bir karma aramaya dönüştürecektir.

Türü dizginin değişmesi sorunu, onu açık bir karma arayışına dönüştürerek ve karma bir yapıda karma karmalarını doldurarak çözülebilir. Bu şekilde karma, çalışma zamanında doğru dizelerle doldurulur, böylece doğru kalır.

1

Durumun sabit olması gerektiğinden, C# anahtarını kullanarak bunu yapamazsınız.

sorununun ne:

if (property.PropertyType == typeof(Boolean)) 
{ 
} 
else if (property.PropertyType == typeof(String)) 
{ 
} 
else if (...) 
{ 
} 
+0

OP zaten farkında olmalıdır. Yine de, reddetmeye karşı koymak için +1; Aynı zamanda geçerli bir çözüm, bazen yerleşik yapıların gücünü değiştirmek imkansız. – nawfal

0

Sadece normal bir kullanma tipeof ile dinamik. Bu çok hızlı çünkü ilk bölüm için - anahtar - derleyici bir arama tablosuna göre karar verebilir.

3

Yapamazsınız. Ne yapabilirsiniz bir sözlük kullanarak Türleri ve bir temsilci arasında bir eşleme yaratmaktır:

var TypeMapping = new Dictionary<Type, Action<string>>(){ 
    {typeof(string), (x)=>Console.WriteLine("string")}, 
    {typeof(bool), (x)=>Console.WriteLine("bool")} 
}; 



string s = "my string"; 

TypeMapping[s.GetType()]("foo"); 
TypeMapping[true.GetType()]("true"); 
0

Geçenlerde benzer bir şey yapmak zorunda ve anahtarı kullanarak bir seçenek değildi. typeof (x) bir == yapmak iyi, ama daha zarif bir şekilde böyle bir şey yapmak için olabilir: Kullanabileceğin emin değilim

if(property.PropertyType is bool){ 
    //dostuff; 
} 
else if (property.PropertyType is string){ 
    //do other stuff; 
} 

Ama anahtar kelime içinde "dir" Bu şekilde, sadece nesneler için çalışır düşünüyorum ...

2

Bence burada aradığınız şey iyi bir Harita. Delegeleri ve Genel bir IDictionary kullanarak istediğinizi yapabilirsiniz.

böyle bir şey deneyin:

private delegate object MyDelegate(); 

private IDictionary<Type, MyDelegate> functionMap = new IDictionary<Type, MyDelegate>(); 

public Init() 
{ 
    functionMap.Add(typeof(String), someFunction); 
    functionMap.Add(tyepof(Boolean), someOtherFunction); 
} 

public T doStuff<T>(Type someType) 
{ 
    return (T)functionMap[someType](); 
} 
1

Ben şahsen Dictionary<Type, other> en yaklaşım tercih ... Hatta sana başka bir örnek sağlayabilir: Bir anahtar-durum yazma durumunda http://www.timvw.be/presenting-namevaluecollectionhelper/

ısrar Eğer Tip adını kullanabilirsiniz deyim ... stringmatching Hakkında

switch (blah.PropertyType.FullName) 
{ 
    case typeof(int).FullName: break; 
    case typeof(string).FullName: break; 
} 
+0

-1, case gerektirir * sabit ifade. * – nawfal

+0

@nawfal Bunu yaptığınız için bunu yaptım yanlış System.String ile çalışır. System.String, değişmez bir türüdür. – toATwork

+1

@toATwork Immutable veya değil, 'case' sabit bir ifade gerektirir. Örneğin Örneğinizdeki System.String, "case" myCompileTimeValue "gibi görünüyorsa:' Bu işe yarayacaktır. Ama eğer 'myRunTime.Value:' örneğine benziyorsa, derleme yapmaz. Nesnelerin eşleştirilmesi ve hepsi ile C# (muhtemelen 7) 'nin gelecek sürümlerinde şeyler değişebilir. – nawfal

0

: o inci bunu söz konusu Reqs biriydi kaba stringmatching.

Bu sözlük, tüm serileştirme algoritmasını kendi kütüphanesine yerleştirdiğimde kullanacağım bir yaklaşım. Şimdilik, ilk olarak, yalnızca temel tipler kullandığım için typeCode'u deneyeceğim. ben de bundan sürüsü geri döner çalışmazsa/birinin ise: S

Kendi seri istiyorum neden ppl ask me önce: 1) .net xml seri hale belirleyiciler olmadan özelliklerini serileştirmez 2) serileştirme bazı eski kurallara uymak zorundadır

+0

Boş bir set ekleyerek özellikler sınırlamasını atlayabilirsiniz. genel dize MyProp {get {return foo;} set {;}} –

1

C# 7.0, daha büyük desen eşleştirme özelliğinin bir parçası olarak türleri açmayı destekleyecektir. Bu örnek yeni özellikler açıkladı .NET blog post alınır:

switch(shape) 
{ 
    case Circle c: 
     WriteLine($"circle with radius {c.Radius}"); 
     break; 
    case Rectangle s when (s.Length == s.Height): 
     WriteLine($"{s.Length} x {s.Height} square"); 
     break; 
    case Rectangle r: 
     WriteLine($"{r.Length} x {r.Height} rectangle"); 
     break; 
    default: 
     WriteLine("<unknown shape>"); 
     break; 
    case null: 
     throw new ArgumentNullException(nameof(shape)); 
}