C# 为什么';对象是否有接受IFormatProvider的重载?
例如,将C# 为什么';对象是否有接受IFormatProvider的重载?,c#,.net,object,globalization,C#,.net,Object,Globalization,例如,将十进制转换为字符串时,使用CultureInfo.InvariantCulture并将其作为IFormatProvider传递。但是为什么这个重载不在对象中呢 一个很好的实现是: public virtual string ToString() { // yadayada, usual ToString } public virtual string ToString(IFormatProvider provider) { return ToString(); } 这不会
十进制
转换为字符串
时,使用CultureInfo.InvariantCulture
并将其作为IFormatProvider
传递。但是为什么这个重载不在对象中呢
一个很好的实现是:
public virtual string ToString()
{
// yadayada, usual ToString
}
public virtual string ToString(IFormatProvider provider)
{
return ToString();
}
这不会对对象
类造成任何伤害或好处,但是从它派生的对象可以替代重载,并且当您不确定类型时,调用重载会容易得多
让我遇到这种情况的问题是,当我创建一个方法时,该方法将获取类的所有属性并将其写入xml。因为我不想检查对象的类型,所以我只调用了ToString
。但是如果这是一个小数,那么输出将基于线程的CurrentCulture
,这不是最佳的。我能看到的唯一解决方法是将CurrentCulture
更改为InvariantCulture
,然后将其更改回以前的状态。但那会很难看,因为我必须写try finally块等等
我目前的代码是:
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());
}
}
但我希望它是:
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));
}
}
在对象上没有此重载有什么好处?尝试将值转换为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));
}
}
Peter解的简便扩展方法(修改为测试IConvertible)
请尝试以下方法之一:
string valueString = XmlConvert.ToString(value);
string valueString = Convert.ToString(value, CultureInfo.InvariantCulture);
ToString()是为XML设计的,因此它将使内容更接近XML规范,例如使用“true”而不是“true”。但是,它也比Convert.ToString()更脆弱。例如,由于UTC时间,这将引发异常:
XmlConvert.ToString(DateTime.UtcNow)
但这是可行的:
XmlConvert.ToString(DateTime.UtcNow, "o")
IConvertible
实际上更有意义(除非你打算格式化数字)。@dlev:我不同意——OP特别想格式化数字。考虑到类型可能很容易实现IFormattable,但不是IFormattable,而且IFormattable中的单个方法正是OP想要调用的方法,我认为IFormattable更有意义。@Jon根据OP的问题,看起来他有实际使用ToString()
版本的IConvertible
的经验,这就是我提到它的原因。您的观点很好理解,不过.Convert.ToString实际上强制转换为IConvertible和IFormattable(请参阅前面的文章):公共静态字符串ToString(对象值,IFormatProvider提供程序){IConvertible ic=value as IConvertible;if(ic!=null)返回ic.ToString(提供程序);IFormattable formattable=作为ifformattable的值;if(formattable!=null)返回formattable.ToString(null,提供程序);返回值==null?String.Empty:value.ToString();}
XmlConvert.ToString(DateTime.UtcNow, "o")