2009-04-09 31 views
43

Bunu gerçekten elde edebilmem gerekir, ancak sormak daha kolay olacağını düşündüğüm noktaya geliyorum. C# fonksiyonunda Dize Dönüştürme <T>

:

public static T GetValue<T>(String value) where T:new() 
{ 
    //Magic happens here 
} 

büyü için iyi bir uygulama nedir? Bunun arkasındaki fikir, ayrıştırmak için xmlim var ve istenen değerler genellikle ilkeldir (bool, int, string, vb.) Ve bu, jeneriklerin kullanımı için mükemmel bir yerdir ... ama şu anda basit bir çözüm beni utandırıyor .

btw burada ben yerine kendinizi TO XML ayrıştırmak çalışmakla öneririm

<Items> 
    <item> 
     <ItemType>PIANO</ItemType> 
     <Name>A Yamaha piano</Name> 
     <properties> 
      <allowUpdates>false</allowUpdates> 
      <allowCopy>true</allowCopy> 
     </properties> 
    </item> 
    <item> 
     <ItemType>PIANO_BENCH</ItemType> 
     <Name>A black piano bench</Name> 
     <properties> 
      <allowUpdates>true</allowUpdates> 
      <allowCopy>false</allowCopy> 
      <url>www.yamaha.com</url> 
     </properties> 
    </item> 
    <item> 
     <ItemType>DESK_LAMP</ItemType> 
     <Name>A Verilux desk lamp</Name> 
     <properties> 
      <allowUpdates>true</allowUpdates> 
      <allowCopy>true</allowCopy> 
      <quantity>2</quantity> 
     </properties> 
    </item> 
</Items> 
+0

Eğer ayrıştırmak için çalışıyoruz sizin XML bir örnek verebilir – bendewey

+0

Dışarı çıkmayı beklediğiniz şeyin bir örneğini sunmak ister misiniz? Bu bağlamda pek çok şey olabilir… bir dizgeyi onlara dönüştürme yeteneğiniz, neyin izin verildiğini tanımlayabileceğinize bağlı olacaktır. POCO – Shog9

cevap

116

ayrıştırmak ihtiyacım olacağını xml örnek, sen sınıfa XML serisini ediyorum sınıfları oluşturmayı deneyin . Bendewey'in cevabını izliyorum şiddetle tavsiye ederim.

Ama bunu yapamazsanız, umut vardır. Convert.ChangeType'u kullanabilirsiniz.

public static T GetValue<T>(String value) 
{ 
    return (T)Convert.ChangeType(value, typeof(T)); 
} 

And You kabaca böyle bir şey ile başlayabilirsiniz böylece

GetValue<int>("12"); // = 2 
GetValue<DateTime>("12/12/98"); 
+0

+1 +1 görüyorum ve size başka bir +1 yükseltmek. Her ne kadar zarafeti ile kafam karışsa da, jenerikler için jenerik kullanıyorum gibi kokuyor. – bendewey

+0

için XML Serileştirme için – jfar

+0

GetValue () - (int) GetValue(): P – Jimmy

5

gibi kullanın:

TypeConverter converter = TypeDescriptor.GetConverter(typeof(T)); 
if (converter != null) 
{ 
    return (T)converter.ConvertFrom(value); 
} 

renkler veya kültür dizeleri gibi özel türleridir özelliklerini, ayrıştırmak varsa ya da değilse, tabii ki yukarıdaki özel durumları yapmak zorunda kalacaksınız. Ancak bu, ilkel türlerinizin çoğunu ele alacaktır.

+0

Eğer GetConverter (typeof (T)) kullanırsanız, t değişkenine veya yeni() –

+0

'a ihtiyacınız yoktur. Belki bir düzenleme yapacağım - teşekkürler. – womp

0

Bunun doğru çalışması için, genel yönteminizin gerçek çalışmasını özel bir sınıfa devretmek zorunda kalacak.

şey _Deserializers size sınıfları kayıt sözlüğe çeşit

private Dictionary<System.Type, IDeserializer> _Deserializers; 
    public static T GetValue<T>(String value) where T:new() 
    { 
     return _Deserializers[typeof(T)].GetValue(value) as T; 
    } 

gibi. (Açıkçası, bir desperizatörün sözlükte kayıtlı olduğundan emin olmak için bazı kontroller gerekli olacaktır).

(burada T Bu durumda:. Yönteminiz herhangi bir nesne oluşturmak gerekmez çünkü

+0

As sınıfı işlecini, sınıf kısıtlaması olmadan genel türlerde kullanamazsınız. – Samuel

+0

woops, bunu bilmiyordum. Hala düzenli bir Cast yapabilirsin? –

4

Eğer Poco'ya serileştirme rotasını (Düz eski CLR Object) gitmeye karar verirseniz yeni() işe yaramaz, o zaman nesneleri oluşturulmasına yardımcı olabilir birkaç araç bulunmaktadır.

  • sen XML tanımı dayalı bir .cs dosyası oluşturmak için xsd.exe kullanabilirsiniz
  • Html olarak Yapıştır denilen WCF REST Starter Kit Preview 2 yeni bir özelliktir vardır
  • Bu özellik gerçekten harika ve bir HTML bloğunu almanıza izin veriyor. Panoya s sonra, bir cs dosyasına yapıştırdığınızda otomatik olarak xml seri hale getirme için CLR nesnesine dönüştürür.Bunu yaparken muhtemelen kötü bir fikir olduğunu ihtar ile tekrar
+0

Seri aktarma, bu işlevin amaçlanan kullanımıyla ilgili sorunun dışındadır. İlk başta Xml <-> poco'yu düşündük, ama xml> 1Mb aralığına ulaştığında, uygulamadan aşağı inmeye başlıyoruz. Patron Xpath –

+0

LINQ gitmenin yolu olduğunu söyledi xpath daha hızlıdır. – bendewey

+0

Bkz. Http://en.wikipedia.org/wiki/XML#Processing_files, XPath, DOM'ı kullanır, Linq to XML, 'çekme ayrıştırma' kullanır – bendewey

0

:

class Item 
{ 
    public string ItemType { get; set; } 
    public string Name { get; set; } 
} 

public static T GetValue<T>(string xml) where T : new() 
{ 
    var omgwtf = Activator.CreateInstance<T>(); 
    var xmlElement = XElement.Parse(xml); 
    foreach (var child in xmlElement.Descendants()) 
    { 
     var property = omgwtf.GetType().GetProperty(child.Name.LocalName); 
     if (property != null) 
      property.SetValue(omgwtf, child.Value, null); 
    } 
    return omgwtf; 
} 

test çalıştırması:

static void Main(string[] args) 
{ 
    Item piano = GetValue<Item>(@" 
     <Item> 
      <ItemType /> 
      <Name>A Yamaha Piano</Name> 
      <Moose>asdf</Moose> 
     </Item>"); 
}