2011-09-22 21 views
27

bir decimal bir string için örneğin dönüştürürken, CultureInfo.InvariantCulture kullanın ve bir IFormatProvider olarak geçmektedir. Fakat bu aşırı yüklenme neden object'da değil?Neden nesne IFormatProvider kabul eden bir aşırı yüklenme yok?

güzel uygulama olacaktır:

public virtual string ToString() 
{ 
    // yadayada, usual ToString 
} 

public virtual string ToString(IFormatProvider provider) 
{ 
    return ToString(); 
} 

Bu, hiçbir zarar veya object sınıfa yarar, ama ondan kaynaklanan nesneler yerine aşırı geçersiz kılabilir ve onu zaman aramak çok daha kolay olacaktır olurdu sen tipinden emin değilsin. Bir sınıfın tüm özelliklerini alma ve xml bunu yazıyor olacağını bir yöntem çıkıyordu zaman

Beni buna çalıştırmak yapılan sorun

oldu. Nesnenin türünü kontrol etmek istemediğimden, sadece ToString'u aradım. Ancak bu bir ondalık olurdu, çıktı, iş parçacığının en uygun olmayan CurrentCulture dayanacaktır. Görebildiğim tek çözüm, CurrentCulture'un InvariantCulture'a değiştirilmesi ve daha sonra, daha önce olduğu gibi geri dönmesidir. Denemek yazmak zorunda gibi Ama bu sadece çirkin olurdu nihayet vb bloklar

Benim şu anki kodudur:

 foreach (var property in typeof(Order).GetProperties(BindingFlags.Public | BindingFlags.Instance). 
      Where(c => ValidTypes.Contains(c.PropertyType))) 
     { 
      var value = property.GetValue(order, null); 
      if (value != null) 
      { 
       writer.WriteElementString(property.Name, 
       value.ToString()); 
      } 
     } 

Ama olmasını isterim:

 foreach (var property in typeof(Order).GetProperties(BindingFlags.Public | BindingFlags.Instance). 
      Where(c => ValidTypes.Contains(c.PropertyType))) 
     { 
      var value = property.GetValue(order, null); 
      if (value != null) 
      { 
       writer.WriteElementString(property.Name, 
       value.ToString(CultureInfo.InvariantCulture)); 
      } 
     } 

Herhangi yarar object'da bu aşırı yüklenme olmaması?

cevap

28

döküm çalışın sizin valueIFormattable için:

foreach (var property in typeof(Order).GetProperties(BindingFlags.Public | BindingFlags.Instance). 
     Where(c => ValidTypes.Contains(c.PropertyType))) 
{ 
    var value = property.GetValue(order, null); 
    if (value != null) 
    { 
     var formattable = value as IFormattable; 
     writer.WriteElementString(property.Name, 
     formattable == null ? value.ToString() : formattable.ToString(null, CultureInfo.InvariantCulture)); 
    } 
} 
+3

'IConvertible' aslında daha mantıklı

XmlConvert.ToString(DateTime.UtcNow, "o") 
dlev

+5

@ dlev: Ben katılmıyorum - OP özellikle biçimlendirmek için * sadece * istiyor. Tipler IFormattable'ı ancak IConvertible'ı kolayca uygulayabildiğine ve IFormattable'daki tek yöntemin OP'nin çağırmak istediği gibi olduğunu düşünürsek, IFormattable'ın daha mantıklı olduğunu düşünüyorum. –

+0

@Jon OP'nin sorusuna dayanarak, 'ToString() '' IConvertible' sürümünü kullanmayla ilgili deneyimi var gibi görünüyor, bu yüzden bundan bahsettim. Yine de, senin puanın iyi. – dlev

14

(IConvertible için de test etmek değiştirilmiş) Peter çözümün Handy uzatma yöntemi.

public static string ToInvariantString(this object obj) 
{ 
    return obj is IConvertible ? ((IConvertible)obj).ToString(CultureInfo.InvariantCulture) 
     : obj is IFormattable ? ((IFormattable)obj).ToString(null, CultureInfo.InvariantCulture) 
     : obj.ToString(); 
} 
8

Bunlardan birini deneyin:

string valueString = XmlConvert.ToString(value); 
string valueString = Convert.ToString(value, CultureInfo.InvariantCulture); 

XmlConvert.ToString() XML için yapılır, bu nedenle böyle "gerçek" yerine "Gerçek kullanma gibi daha yakın XML spec şeyler tutacak ". Ancak, aynı zamanda Convert.ToString() 'den daha kırılgandır.

XmlConvert.ToString(DateTime.UtcNow) 

ama bu işler: Örneğin, bu çünkü UTC zaman bir özel durum oluşturur (. Numarayı biçimlendirmek için plan sürece)

+2

Convert.ToString aslında IConvertible ve IFormattable (önceki makalelere bakın): genel statik dize ToString (Nesne değeri, IFormatProvider sağlayıcısı) { IConvertible ic = IConvertible olarak değer; if (ic!= null) return ic.ToString (sağlayıcı); IFormattable formattable = IFormattable olarak değer; if (formattable! = Null) dönüş formatı.ToString (boş, sağlayıcı); dönüş değeri == null? String.Empty: value.ToString(); } –

İlgili konular