Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
365 views
in Technique[技术] by (71.8m points)

c# - Why doesn't object have an overload that accepts IFormatProvider?

When converting for instance a decimal to a string, you use the CultureInfo.InvariantCulture and pass it as an IFormatProvider. But why is this overload not in object?

A nice implementation would be:

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

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

This would cause no harm or benefit to the object class, but objects deriving from it can instead override the overload and it will be a lot easier to call it when you are unsure of the type.

The problem that made me run into this was when I was making a method that would be getting all properties of a class and writing it to xml. As I didn't want to check the type of the object, I just called ToString. But would this have been a decimal, the output would be based on the CurrentCulture of the thread, which is not optimal. The only workaround I can see is changing the CurrentCulture to InvariantCulture and then changing it back to whatever it was before. But that would just be ugly as I would have to write try finally blocks etc.

My current code is:

        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());
            }
        }

But I would want it to be:

        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));
            }
        }

Any benefit of not having this overload on object?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Try to cast your value to IFormattable:

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));
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...