请描述一下GetFormat的工作方法。下面我给出了该方法的典型示例。当我们调用string.Format以及为什么我们返回“this”时,我不会在“formatType”中放置什么对象?
感谢您的回答。
class TimeWordFormatter : IFormatProvider, ICustomFormatter
{
static readonly string[] hours = { "h", "hours", "H" };
static readonly string[] minutes = { "m", "minutes", "M" };
static readonly string[] seconds = { "s", "seconds", "S" };
public object GetFormat(Type formatType)
{
if (formatType == typeof(ICustomFormatter))
{
return this;
}
else
{
return null;
}
}
public string Format(string format, object arg, IFormatProvider formatProvider)
{
if (arg == null || !(arg is TimeSpan) || format != "W")
return string.Format("{0:" + format + "}", arg);
TimeSpan time = (TimeSpan)arg;
string hh = GetCase(time.Hours, hours);
string mm = GetCase(time.Minutes, minutes);
string ss = GetCase(time.Seconds, seconds);
return string.Format("{0:%h} {1} {0:%m} {2} {0:%s} {3}", time, hh, mm, ss);
}
static string GetCase(int value, string[] options)
{
value = Math.Abs(value) % 100;
if (value > 10 && value < 15)
return options[2];
value %= 10;
if (value == 1) return options[0];
if (value > 1 && value < 5) return options[1];
return options[2];
}
static void Main()
{
var now = DateTime.Now;
string formattedTime = string.Format(new TimeWordFormatter(), "{0:W}", now.TimeOfDay);
Console.WriteLine(formattedTime);
}
}
答案 0 :(得分:0)
I don't undersand what object we put in "formatType"
查看方法签名。 formatType
是Type
。你传递Type
。它是在IFormatProvider中定义的,因此您可能不需要自己调用它。还有一些其他方法需要IFormatProvider
,因此可以调用GetFormat
。
至于回归this
。 IFormatProvider
有一个方法GetFormat
,它返回Type
传递给GetFormat
的对象。在这种情况下,执行该操作的对象与实现TimeWordFormatter
的{{1}}相同(因为它还实现了GetFormat
)。所以它只返回C#关键字ICustomFormatter
的当前实例。
答案 1 :(得分:0)
我正在拔头发时着陆在这里,试图根据Microsoft的文档来理解,如果我想使用GetFormat(Type formatType)
方法,它将被调用什么值,何时以及多少次?在string.Format
电话中。是每个string.Format
调用仅调用一次,还是为我为字符串模式提供的每个参数调用它? (可能)被调用的是什么其他类型(而不是ICustomFormatter
),那么为什么我们必须返回null
?这到底如何工作?理解大局将是一件很高兴的事。但是不,它没有记录在案!
相反,我们有非常“有用的”文档,例如
其IFormatProvider.GetFormat方法确定formatType是否 参数表示ICustomFormatter类型。如果有的话 BinaryFormatter返回自身的一个实例;否则返回 空。
上面的代码示例。谢谢微软,这真是太好了!
我最终做了一个虚拟IFormatProvider
实现的实验:
class Test : IFormatProvider
{
public object GetFormat(Type formatType)
{
return null;
}
}
并这样称呼它:
string.Format(new Test(), pattern, arguments);
其中arguments
是一个包含2个字符串的数组,而pattern
是一个具有2个占位符的字符串。
这是调用堆栈:
Test.GetFormat(System.Type formatType)第34行C# mscorlib.dll!System.Text.StringBuilder.AppendFormatHelper(System.IFormatProvider提供程序,字符串格式,System.ParamsArray args)未知 mscorlib.dll!string.FormatHelper(System.IFormatProvider提供程序,字符串格式,System.ParamsArray参数) mscorlib.dll!string.Format(System.IFormatProvider提供程序,字符串格式,对象[] args)未知
因此,System.Text.StringBuilder.AppendFormatHelper
是解决我们所有问题的方法。验证一下:https://referencesource.microsoft.com/#mscorlib/system/text/stringbuilder.cs,2c3b4c2e7c43f5a4,references
事实证明,GetFormat
仅被调用一次,除typeof(ICustomFormatter)
之外,其他任何类型都不会被调用。如果是其他类型的参数,则返回null可能只是为了将来的合规性!