我正在使用Datetime.ParseExact方法,它需要一个IFormatProvider ...
它可以输入null,但它到底是做什么的?
如果我们使用该ParseExact方法使用指定的格式进行精确的日期时间解析,为什么我们需要提供IFormatProvider对象?它的背后有什么意义?
例如:
DateTime.ParseExact(dateString, format, provider);
Run Code Online (Sandbox Code Playgroud)
我们为什么需要provider这里?
我试图创建一个IFormatProvider可以识别DateTime对象的自定义格式字符串的实现.这是我的实现:
public class MyDateFormatProvider : IFormatProvider, ICustomFormatter
{
public object GetFormat(Type formatType)
{
if (formatType == typeof(ICustomFormatter))
{
return this;
}
return null;
}
public string Format(string format, object arg, IFormatProvider formatProvider)
{
if(arg == null) throw new ArgumentNullException("arg");
if (arg.GetType() != typeof(DateTime)) return arg.ToString();
DateTime date = (DateTime)arg;
switch(format)
{
case "mycustomformat":
switch(CultureInfo.CurrentCulture.Name)
{
case "en-GB":
return date.ToString("ddd dd MMM");
default:
return date.ToString("ddd MMM dd");
}
default:
throw new FormatException();
}
}
Run Code Online (Sandbox Code Playgroud)
我希望能够在这样的DateTime.ToString(string format, IFormatProvider provider) …
如何将IFormatProvider传递给StreamWriter?
具体来说我想创建一个
new StreamWriter("myfile.txt", CultureInfo.InvariantCulture);
TextWriter和StringWriter在构造函数中有一个参数,但StreamWriter没有.
属性stringWriter.FormatProvider是readonly.
我可以想到三个似乎不好的解决方案:
有没有办法为StreamWriter指定FormatProvider?如果我可以设置属性,则基于TextWriter的继承,StreamWriter必须具有处理此功能的方法.
我们目前正在使用以下内容在我们的网络应用程序中创建美元价值:
string.Format("{0:C0}", dollarValue );
Run Code Online (Sandbox Code Playgroud)
在这个例子中,如果dollarValue是145,那么我们将看到:145美元.如果它是-145,那么我们将看到(145美元)而不是 - 145美元.请注意,对于我们来说,dollarValue是一个double,但它可以是任何数字类型.我认为.
无论如何,我想要的是145美元或145美元.
现在,根据我的研究,使用NumberFormatInfo类可能会这样做.我无法弄清楚如何使用它,我找不到任何有效的例子.我确实在这里看到了这个问题:当货币值为0.00美元时,C#创建一个自定义的NumberFormatInfo来显示"Free"但是来自这个问题的MSDN示例似乎与我真正想做的有点不同.
我意识到,我需要做以下事情:
double dollarValue = -145d;
string myMoney = dollarValue.ToString( "C0", someIFormatProvider );
Run Code Online (Sandbox Code Playgroud)
someIFormatProvider可能是NumberFormatInfo类型.现在,我所做的就是:
NumberFormatInfo ni = new NumberformatInfo();
ni.CurrencyNegativePattern = 1; // The value 1 should mean not to use parenthesis
string myMoney = dollarValue.ToString( "C0", ni );
Run Code Online (Sandbox Code Playgroud)
...我得到一个"Instance is Read-Only"异常.虽然CurrencyNegativePattern属性的"文档"说你可以设置和获取值,但显然你不能.此外,NumberFormatInfo是一个密封类.我不能轻易地创建一个基于它的新类并覆盖该值.
我不知道如何处理这个问题.现在,我的解决方法是只是否定我的负面价值,并得到一个积极的结果,我string.Format(...)再次做.是的,我意识到前面没有负面的迹象,但是,当然,通过在结果前面根据需要添加" - "可以很容易地解决这个问题.
有人能够为我提供一个如何在这种情况下正确有效地使用NumbefFormatInfo类的工作示例吗?谢谢.
我想知道为什么代码分析规则CA1305 - 指定IFormatProvider不适用于TryParse方法?
例如,使用"Microsoft All Rules"规则集,代码分析会针对以下代码提供CA1305警告:
static void Main(string[] args)
{
string text = args[0];
double value = double.Parse(text);
}
Run Code Online (Sandbox Code Playgroud)
但是没有给出以下代码的CA1305警告:
static void Main(string[] args)
{
string text = args[0];
double value;
if (!double.TryParse(text, out value))
value = 0;
}
Run Code Online (Sandbox Code Playgroud)
我发现这非常不幸,因为如果输入字符串不可靠,TryParse方法是解析的正确方法.
有谁知道TryParse方法的CA1305规则是在某些较新版本的代码分析工具中实现还是由某些第三方实现?
我有以下两行代码:
var BadResult = (100).ToString("B", new CustomFormatter ());
var GoodResult = String.Format("{0}", 100, new CustomFormatter ());
Run Code Online (Sandbox Code Playgroud)
然而,BadResult显然很糟糕,GoodResult很好.我的CustomFormatter类声明如下:(同样,我认为一个函数是相关的):
public class CustomFormatter
: IFormatProvider, ICustomFormatter
{
public virtual Object GetFormat(Type formatType)
{
String formatTypeName = formatType.ToString();
formatTypeName = formatTypeName;
Object formatter = null;
if (formatType == typeof(ICustomFormatter))
formatter = this;
return formatter;
}
}
Run Code Online (Sandbox Code Playgroud)
问题本身,当我运行具有"良好结果"的代码行时,GetFormat函数是requestng一个CustomFormatter的实例.
每当用Float.Tostring()调用它时,它期望一个NumberFormatInfo的实例.
我最初跳到"我的CustomFormatter应该从NumberFormatInfo派生".不幸的是,课程是密封的.
那么: 我需要做什么才能用自定义格式化程序调用Float.ToString()?
谢谢!
C#中的字符串格式;
我可以用吗?是.
我可以实现自定义格式吗?没有.
我需要写一些可以传递一组自定义格式选项的内容string.Format,这会对特定项目产生一些影响.
目前我有这样的事情:
string.Format("{0}", item);
Run Code Online (Sandbox Code Playgroud)
但我希望能够用这个项目做事:
string.Format("{0:lcase}", item); // lowercases the item
string.Format("{0:ucase}", item); // uppercases the item
string.Format("{0:nospace}", item); // removes spaces
Run Code Online (Sandbox Code Playgroud)
我知道我可以做类似的事情.ToUpper(),.ToLower()但我需要用字符串格式化来做.
我一直在研究类似的事情IFormatProvider,IFormattable但我不知道它们是否应该是我应该使用的东西,或者,如何实现它们.
任何人都可以解释我如何解决这个问题?
理由(以防万一你想知道...)
我有一个小程序,我可以在其中输入逗号分隔的值集和模板.项目将string.Format与创建输出的模板一起传递.我想提供模板格式化选项,以便用户可以控制他们想要输出项目的方式.
在尝试在如何在DataGridView中自定义TimeSpan的DataGridView列中的Format TimeSpan之后,我试图弄清楚IFormatProvider和ICustomFormatter的工作方式。我创建了一个完全自定义的格式化程序,无论格式化的是什么格式,该格式化程序始终返回“ foo”。
我在Int上使用它,但我认为它应该对所有类型都适用,因为它不检查传递的值,而只是返回"foo"。
class MyFormatter : IFormatProvider, ICustomFormatter
{
public object GetFormat(Type formatType)
{
Console.WriteLine("GetFormat");
return this;
}
public string Format(string format, object arg, IFormatProvider formatProvider)
{
Console.WriteLine("Format");
return "foo";
}
}
Run Code Online (Sandbox Code Playgroud)
我将其传递给int.ToString():
int number = 10;
Console.WriteLine(number.ToString(new MyFormatter()));
Run Code Online (Sandbox Code Playgroud)
我得到的是:
GetFormat 10
我希望得到的是:
GetFormat 格式 富
编辑:我发现如何为DateTime创建和使用自定义IFormatProvider?并且那里的答案说DateTime.ToString()不会接受任何东西,但是DateTimeFormatInfo或CultureInfo和即使该对象实现了以下类型的对象也将被拒绝-https ICustomFormatter: //stackoverflow.com/a/2382481/492336。
因此,我的问题是,在所有情况下该ToString()方法都适用吗?它也适用于DataGridView吗?在哪种情况下,我可以传递真正的自定义格式化程序?
我尝试在我们的产品的几个程序集上运行FxCop,并且我获得了许多匹配"Specify IFormatProvider"规则.
碰巧,其中一些是合法的,但它也匹配这样的代码:
Logger.DebugFormat("Appending file {0}", fileName);
Run Code Online (Sandbox Code Playgroud)
哪个可以写成
Logger.DebugFormat(CultureInfo.InvariantCulture, "Appending file {0}", fileName);
Run Code Online (Sandbox Code Playgroud)
第二种变体更难阅读.
那么,它是否真的建议始终指定IFormatProvider或者"仅仅"是规则中使用的启发式的限制?
iformatprovider ×10
c# ×8
.net ×3
asp.net ×1
cultureinfo ×1
datetime ×1
filestream ×1
formatting ×1
fxcop ×1
iformattable ×1
streamwriter ×1
string ×1
tryparse ×1