c# ToString( provider)

用这个public static string ToString (
int value,
IFormatProvider provider
)

我想把在数字里插入“&”,如:convert.ToString(123,provider1),输出是
&1&2&3&
谁能帮忙写个provider。
谢谢各位。
我还是觉得convert.ToString(123,provider1)好用一点。能写一个吗。

谢谢 yatasoft的研究。
我想问问,你是怎样知道它的源码的呢?微软不是不公开吗?

好东西,谢谢分享。
请问,有什么api的辅助工具吗?

今天想让textbox的MouseUp时,执行一段代码,
可是发现在执行这段代码前,会弹出右键菜单(点击鼠标右键),
有什么办法移除弹出右键菜单的动作吗?
调试发现没法看到MouseUp的内容。

using System;
using System.Collections.Generic;
using System.Text;

namespace unitTestCase
{
public class AcctNumberFormat : IFormatProvider, ICustomFormatter
{

public object GetFormat(Type formatType)
{
if (formatType == typeof(ICustomFormatter))
return this;
else
return null;
}

public string Format(string fmt, object arg, IFormatProvider formatProvider)
{
// Convert argument to a string
string argString = arg.ToString();

//new a StringBuilder in argString
StringBuilder sb = new StringBuilder(argString);

if(sb.Length<=1){
return argString;
}

// split sb,and jion in with fmt
StringBuilder sbResult = new StringBuilder();

//append index 0 char
sbResult.Append(sb[0]);
for (int i = 1; i < sb.Length; i++)
{
sbResult.Append(fmt);
sbResult.Append(sb[i]);
}
return sbResult.ToString();
}
}

}

单元测试(注意需要nunit框架测试)

using System;
using System.Collections.Generic;
using System.Text;

using NUnit.Framework;
namespace unitTestCase
{
[TestFixture]
public class AcctNumberFormatTest
{
[Test]
public void FormatTest()
{
int acctNumber1 = 99876;
Assert.AreEqual("9&9&8&7&6", String.Format(new AcctNumberFormat(), "{0:&}", acctNumber1));

int acctNumber2 = 1;
Assert.AreEqual("1", String.Format(new AcctNumberFormat(), "{0:&}", acctNumber2));

int acctNumber3 = 11;
Assert.AreEqual("1&1", String.Format(new AcctNumberFormat(), "{0:&}", acctNumber3));

}

}
}

这个是我帮你刚刚写好的,不过我做的可以在String.Format()方法使用,因为我需要一个"{0:&}"分隔字串的参数,所以和你说的convert.ToString(123,provider1)有点小区别,如果你愿意,用String.Format一样使用。
——————所有权:yatasoft和提问者,转载答案需指出来源。

我研究了下微软的源码。
public static string ToString(int value, IFormatProvider provider)
{
return value.ToString(provider);
}
这里value是System.Number类型,调ToString(provider)内部如下实现:
public string ToString(IFormatProvider provider)
{
return Number.FormatInt32(this, null, NumberFormatInfo.GetInstance(provider));
}
这个NumberFormatInfo.GetInstance(provider) 是数字格式化信息的方法,内容实现如下:
public static NumberFormatInfo GetInstance(IFormatProvider formatProvider)
{
NumberFormatInfo numInfo;
CultureInfo info2 = formatProvider as CultureInfo;
if ((info2 != null) && !info2.m_isInherited)
{
numInfo = info2.numInfo;
if (numInfo != null)
{
return numInfo;
}
return info2.NumberFormat;
}
numInfo = formatProvider as NumberFormatInfo;
if (numInfo != null)
{
return numInfo;
}
if (formatProvider != null)
{
numInfo = formatProvider.GetFormat(typeof(NumberFormatInfo)) as NumberFormatInfo;
if (numInfo != null)
{
return numInfo;
}
}
return CurrentInfo;
}

最终代码将会formatProvider != null因为这个,调到这里,现在我来告诉你吧,
Convert.ToString(int value, IFormatProvider provider)
这个provider不是我们自定义的,而是NumberFormatInfo(因为是整数,如果是日期则为DateTimeFormatInfo)类型的对象,

注意:NumberFormatInfo是这么定义的:
public sealed class NumberFormatInfo : ICloneable, IFormatProvider

看来微软帮你写死了,NumberFormatInfo继承IFormatProvider,但是你因为其是sealed(密封)而无法泛化出自己的子类,到此也许楼主看明白了,用Convert.Tostring()这个方法的provider参数必须是微软NumberFormatInfo的实例,而不是你客户自定义的。

刚刚我通过http://blog.csdn.net/majiabao123/archive/2009/04/09/4059776.aspx
这篇博文发现如果自定义一个类可以用object的类型调用tostring();

具体看新代码如下:
首先定义一个类包装下整形
using System;
using System.Collections.Generic;
using System.Text;

namespace unitTestCase
{
public class MyInt32 : IFormattable
{
private Int32 i;
public MyInt32()
{
i = 0;
}
public MyInt32(Int32 i)
{
this.i = i;
}

public string ToString(string format, IFormatProvider formatProvider)
{
ICustomFormatter icf = formatProvider as ICustomFormatter;
if (icf != null)
{
return icf.Format(null, this.i, formatProvider);
}
return i.ToString();
}
}
}

//格式化提供者代码
using System;
using System.Collections.Generic;
using System.Text;

namespace unitTestCase
{
public class NumberFormat : IFormatProvider, ICustomFormatter
{

public object GetFormat(Type formatType)
{
if (formatType == typeof(ICustomFormatter))
return this;
else
return null;
}

public string Format(string fmt, object arg, IFormatProvider formatProvider)
{
string s;
IFormattable formattable = arg as IFormattable;
if (formattable == null) s = arg.ToString();
else s = formattable.ToString(fmt, formatProvider);

//new a StringBuilder in argString
StringBuilder sb = new StringBuilder(s);

if(sb.Length<=1){
return s;
}

if (arg.GetType() == typeof(Int32))
{
// split sb,and jion in with fmt
StringBuilder sbResult = new StringBuilder();

//append index 0 char
sbResult.Append(sb[0]);
for (int i = 1; i < sb.Length; i++)
{
sbResult.Append("&");
sbResult.Append(sb[i]);
}
return sbResult.ToString();
}
return s;

}
}

}

//单元测试展示使用方法

using System;
using System.Collections.Generic;
using System.Text;

using NUnit.Framework;
namespace unitTestCase
{
[TestFixture]
public class AcctNumberFormatTest
{
[Test]
public void FormatTest()
{
int acctNumber1 = 99876;
MyInt32 mi = new MyInt32(acctNumber1);
Assert.AreEqual("9&9&8&7&6", Convert.ToString(mi, new NumberFormat()));
}

}
}

这里的代码可能最接近了,不过需要自己定义一个类,这样就绕过了int需要微软的number.tosting的方法,调用自己的方法,这么做就是为了解决无法创建灵活的NumberFormatInfo实例。

.net reflector 可以反编译程序集看到源码,我经常用这个查找微软内部源码的实现,下载地址http://www.red-gate.com/products/reflector/
温馨提示:答案为网友推荐,仅供参考
第1个回答  2020-03-13
using
System;
using
System.Collections.Generic;
using
System.Text;
namespace
unitTestCase
{
public
class
AcctNumberFormat
:
IFormatProvider,
ICustomFormatter
{
public
object
GetFormat(Type
formatType)
{
if
(formatType
==
typeof(ICustomFormatter))
return
this;
else
return
null;
}
public
string
Format(string
fmt,
object
arg,
IFormatProvider
formatProvider)
{
//
Convert
argument
to
a
string
string
argString
=
arg.ToString();
//new
a
StringBuilder
in
argString
StringBuilder
sb
=
new
StringBuilder(argString);
if(sb.Length<=1){
return
argString;
}
//
split
sb,and
jion
in
with
fmt
StringBuilder
sbResult
=
new
StringBuilder();
//append
index
0
char
sbResult.Append(sb[0]);
for
(int
i
=
1;
i
<
sb.Length;
i++)
{
sbResult.Append(fmt);
sbResult.Append(sb[i]);
}
return
sbResult.ToString();
}
}
}
单元测试(注意需要nunit框架测试)
using
System;
using
System.Collections.Generic;
using
System.Text;
using
NUnit.Framework;
namespace
unitTestCase
{
[TestFixture]
public
class
AcctNumberFormatTest
{
[Test]
public
void
FormatTest()
{
int
acctNumber1
=
99876;
Assert.AreEqual("9&9&8&7&6",
String.Format(new
AcctNumberFormat(),
"{0:&}",
acctNumber1));
int
acctNumber2
=
1;
Assert.AreEqual("1",
String.Format(new
AcctNumberFormat(),
"{0:&}",
acctNumber2));
int
acctNumber3
=
11;
Assert.AreEqual("1&1",
String.Format(new
AcctNumberFormat(),
"{0:&}",
acctNumber3));
}
}
}
这个是我帮你刚刚写好的,不过我做的可以在String.Format()方法使用,因为我需要一个"{0:&}"分隔字串的参数,所以和你说的convert.ToString(123,provider1)有点小区别,如果你愿意,用String.Format一样使用。
——————所有权:yatasoft和提问者,转载答案需指出来源。
我研究了下微软的源码。
public
static
string
ToString(int
value,
IFormatProvider
provider)
{
return
value.ToString(provider);
}
这里value是System.Number类型,调ToString(provider)内部如下实现:
public
string
ToString(IFormatProvider
provider)
{
return
Number.FormatInt32(this,
null,
NumberFormatInfo.GetInstance(provider));
}
这个NumberFormatInfo.GetInstance(provider)
是数字格式化信息的方法,内容实现如下:
public
static
NumberFormatInfo
GetInstance(IFormatProvider
formatProvider)
{
NumberFormatInfo
numInfo;
CultureInfo
info2
=
formatProvider
as
CultureInfo;
if
((info2
!=
null)
&&
!info2.m_isInherited)
{
numInfo
=
info2.numInfo;
if
(numInfo
!=
null)
{
return
numInfo;
}
return
info2.NumberFormat;
}
numInfo
=
formatProvider
as
NumberFormatInfo;
if
(numInfo
!=
null)
{
return
numInfo;
}
if
(formatProvider
!=
null)
{
numInfo
=
formatProvider.GetFormat(typeof(NumberFormatInfo))
as
NumberFormatInfo;
if
(numInfo
!=
null)
{
return
numInfo;
}
}
return
CurrentInfo;
}
最终代码将会formatProvider
!=
null因为这个,调到这里,现在我来告诉你吧,
Convert.ToString(int
value,
IFormatProvider
provider)
这个provider不是我们自定义的,而是NumberFormatInfo(因为是整数,如果是日期则为DateTimeFormatInfo)类型的对象,
注意:NumberFormatInfo是这么定义的:
public
sealed
class
NumberFormatInfo
:
ICloneable,
IFormatProvider
看来微软帮你写死了,NumberFormatInfo继承IFormatProvider,但是你因为其是sealed(密封)而无法泛化出自己的子类,到此也许楼主看明白了,用Convert.Tostring()这个方法的provider参数必须是微软NumberFormatInfo的实例,而不是你客户自定义的。
刚刚我通过http://blog.csdn.net/majiabao123/archive/2009/04/09/4059776.aspx
这篇博文发现如果自定义一个类可以用object的类型调用tostring();
具体看新代码如下:
首先定义一个类包装下整形
using
System;
using
System.Collections.Generic;
using
System.Text;
namespace
unitTestCase
{
public
class
MyInt32
:
IFormattable
{
private
Int32
i;
public
MyInt32()
{
i
=
0;
}
public
MyInt32(Int32
i)
{
this.i
=
i;
}
public
string
ToString(string
format,
IFormatProvider
formatProvider)
{
ICustomFormatter
icf
=
formatProvider
as
ICustomFormatter;
if
(icf
!=
null)
{
return
icf.Format(null,
this.i,
formatProvider);
}
return
i.ToString();
}
}
}
//格式化提供者代码
using
System;
using
System.Collections.Generic;
using
System.Text;
namespace
unitTestCase
{
public
class
NumberFormat
:
IFormatProvider,
ICustomFormatter
{
public
object
GetFormat(Type
formatType)
{
if
(formatType
==
typeof(ICustomFormatter))
return
this;
else
return
null;
}
public
string
Format(string
fmt,
object
arg,
IFormatProvider
formatProvider)
{
string
s;
IFormattable
formattable
=
arg
as
IFormattable;
if
(formattable
==
null)
s
=
arg.ToString();
else
s
=
formattable.ToString(fmt,
formatProvider);
//new
a
StringBuilder
in
argString
StringBuilder
sb
=
new
StringBuilder(s);
if(sb.Length<=1){
return
s;
}
if
(arg.GetType()
==
typeof(Int32))
{
//
split
sb,and
jion
in
with
fmt
StringBuilder
sbResult
=
new
StringBuilder();
//append
index
0
char
sbResult.Append(sb[0]);
for
(int
i
=
1;
i
<
sb.Length;
i++)
{
sbResult.Append("&");
sbResult.Append(sb[i]);
}
return
sbResult.ToString();
}
return
s;
}
}
}
//单元测试展示使用方法
using
System;
using
System.Collections.Generic;
using
System.Text;
using
NUnit.Framework;
namespace
unitTestCase
{
[TestFixture]
public
class
AcctNumberFormatTest
{
[Test]
public
void
FormatTest()
{
int
acctNumber1
=
99876;
MyInt32
mi
=
new
MyInt32(acctNumber1);
Assert.AreEqual("9&9&8&7&6",
Convert.ToString(mi,
new
NumberFormat()));
}
}
}
这里的代码可能最接近了,不过需要自己定义一个类,这样就绕过了int需要微软的number.tosting的方法,调用自己的方法,这么做就是为了解决无法创建灵活的NumberFormatInfo实例。
.net
reflector
可以反编译程序集看到源码,我经常用这个查找微软内部源码的实现,下载地址http://www.red-gate.com/products/reflector/
第2个回答  2009-05-22
如果你是用
convert.ToString(123,provider1)
这个provider1参数好像是用System.Globalization.NumberFormatInfo(已经实现了IFormatProvider)
另外如果是如:String.Format(IFormatProvider, string format, Object[] args)
参看:
http://www.cnblogs.com/bear831204/archive/2008/11/03/1325608.html
第3个回答  2009-05-25
convert.ToString(123,provider1) 这个东西,不能实现你说的功能,因为这个provider1不提供格式功能,需要用format
第4个回答  2009-05-22
public void provider(string s)
{
string str = string.Empty;
for (int i = 0; i < s.Length; ++i)
{
str += s[i] + "&";
}
Console.WriteLine(str);
}