重写的ToString()用于调试和日志 - 应该字符串进行本地化?重写、字符串、日志、ToString

2023-09-04 02:37:06 作者:空灵り

我设计将用于其他开发人员使Web和桌面应用程序的.NET库。我重写的ToString()在不同的类提供调试信息的目的,列入应用程序日志文件。

I'm designing a .NET library that will be used by other developers making both web and desktop applications. I'm overriding ToString() in various classes to provide information for debugging purposes and for inclusion in application log files.

我的一些类都包含数字和日期。

Some of my classes contain numbers and dates.

考虑一个对象,它包含一个的DateTime 名为日期名为(也许其他领域也一样)......如果我重写该对象的的ToString(),我可能想要做的是这样的:

Consider an object that contains a DateTime called date and a double called value (and maybe other fields as well)... If I override that object's ToString(), I might want to do something like:

public override string ToString() {
    return "ObjectName[date=" + date + ", value=" + value + "]";
}

但是,这将包括从结果与Date.toString() value.ToString(),这将给我按 Thread.CurrentThread.CurrentCulture 本地化字符串。

But that will include the result from date.ToString() and value.ToString(), which will give me strings that are localized according to Thread.CurrentThread.CurrentCulture.

而这,对我来说,似乎是错误的。我的的ToString返回的字符串()的实施都是为了调试和日志信息,而不是用户界面。所以我觉得回到本地化字符串只能混淆问题。如果2341出现在日志文件中,开发人员需要知道的价值线程的的CurrentCulture 来知道它是否意味着2000 341或2点341它更混淆与日期 - 就像一个字符串XX / XX / XXXX可DD / MM / YYYY或MM / DD / YYYY。我不希望我的的ToString()方法来创建之类的模糊性。

And that, to me, seems wrong. The strings returned by my ToString() implementations are meant for debugging and log messages, not for user interfaces. So I think returning localized strings could only confuse matters. If "2,341" appears in log files, a developer would need to know the value of the thread's CurrentCulture to know whether it meant 2 thousand 341 or 2 point 341. It's even more confusing with dates - a string like xx/xx/xxxx could be dd/mm/yyyy or mm/dd/yyyy. I don't want my ToString() methods to create that sort of ambiguity.

所以,我的倾向是让我的的ToString()方法不区分区域性的,以确保所有返回的字符串是跨文化一致。例如,在内部我的的ToString()方法会不喜欢 value.ToString(CultureInfo.InvariantCulture)来格式化数字。

So my inclination is to make my ToString() methods culture-insensitive, to ensure that all returned strings are consistent across cultures. For example, internally my ToString() methods would do like value.ToString(CultureInfo.InvariantCulture) to format a number.

不过,在.NET库规范似乎是使用的CurrentCulture 默认无参数的ToString()实现。有一个的ToString许多对象()方法也有一个的ToString(IFormatProvider的)的方法为好。这是因为如果.NET的设计师决定,默认使用的ToString()应该是用户界面显示(本地化),以及调试和日志(您倒是需要调用的ToString(CultureInfo.InvariantCulture))都是次要的。

However, the norm in .NET libraries seems to be to use CurrentCulture in default no-args ToString() implementations. Many objects that have a ToString() method also have a ToString(IFormatProvider) method as well. It's as if the designers of .NET decided that the default use of ToString() should be for user-interface display (localized), and that debugging and logs (for which you'd need to call ToString(CultureInfo.InvariantCulture)) are secondary.

所以,如果我实现我的的ToString()方法,一种文化不敏感的方式,我觉得我会去对粮食几分。但似乎傻了创建文化敏感字符串默认情况下,当文化敏感性是没有意义的日志文件或调试。

So if I implement my ToString() methods in a culture-insensitive way, I feel I'd be going against the grain somewhat. But it seems silly to create culture-sensitive strings by default, when culture-sensitivity makes no sense for log files or debugging.

我可以使用的CurrentCulture 来重新present数字和日期在我的默认的ToString()实施,并且还提供了的ToString(FormatProvider)方法,使人们可以得到一个文化不敏感字符串在日志文件等使用,但似乎愚蠢的,因为它只是迫使开发者编写更多code拿到,我猜他们会想(他们是否已经考虑与否)的文化字符串。

I could use the CurrentCulture to represent numbers and dates in my default ToString() implementations, and also provide ToString(FormatProvider) methods so that people can get a culture-insensitive string for use in log files etc. But that seems dumb as it's just forcing developers to write more code to get the culture-insensitive string that I'm guessing they'll want (whether they've considered it or not).

底线是,像的ObjectName [值= 12.234,日期= 2011-10-01] 不应该永远出现在用户界面,那么为什么一个字符串将一个程序员曾经希望它被本地化?

The bottom line is that a string like ObjectName[value=12.234, date=2011-10-01] shouldn't ever appear in a user interface, so why would a programmer ever want it to be localized?

我一直在阅读的框架设计指南的建议实施的ToString()。有些意见似乎有点矛盾。例如:

I've been reading the advice in Framework Design Guidelines on implementing ToString(). Some of the advice seems somewhat contradictory. For example:

我觉得的ToString 一个特别危险的方法以提供UI泛型类型,因为它可能在考虑一些特定的用户界面来实现,使其失去了其他UI需要。为了避免诱惑我这样,我preFER让我的的ToString 输出怪异地强调,只有人应该见过的输出是开发商人类(亚种都属于自己)。

I consider ToString an especially dangerous method to provide for UI-generic types, because it's likely to be implemented with some specific UI in mind, making it useless for other UI needs. To avoid tempting myself in this way, I prefer to make my ToString output as geeky as possible to emphasize that the only "humans" that should ever see the output are "developer humans" (a subspecies all their own).

的ToString 的最重要的价值在于,调试器使用它作为展示对象的默认方式。

The most important value of ToString is that the debugger uses it as the default way of displaying the object.

真的不似乎适合搭配:

DO 返回文化相关的信息时字符串格式化根据当前线程的文化。

得帆云 产品更新日志 20201017

DO string formatting based on the current thread culture when returning culture-dependent information.

使用一个线程的的CurrentCulture 属性返回的的CultureInfo 实例来格式化任何数字或日期

use the CultureInfo instance returned by a thread's CurrentCulture property to format any numeric or date

我完全遵循的准则,并编写的API,做程序员的期望。但是,如果的ToString()是程序员,那么它看起来愚蠢的本地化。 C#编译器不会让使用系统相关的十进制分隔程序员写一个双字面值,那么肯定的ToString()程序员编写的方法应该表现相似?

I'm all for following the guidelines, and writing APIs that do what programmers expect. But if ToString() is for programmers, then it seems silly to localize it. The C# compiler won't let a programmer write a double literal using a system-dependent decimal separator, so surely ToString() methods written for programmers should behave similarly?

你怎么看? 当从输出的ToString()是没有的用于在用户界面的使用,应该在它的数字和日期进行本地化还是不?

What do you think? When the output from ToString() is not intended for use in a user-interface, should the numbers and dates within it be localized or not?

更新

我没有使用 DebuggerDisplay 属性一些测试,它看起来像,在默认情况下,它的格式在文化不敏感的方式号码。

I did some tests using the DebuggerDisplay attribute, and it looks like, by default, it formats numbers in a culture-insensitive way.

[DebuggerDisplay("[value={value}]")]
class DoubleHolder {
    private double value;
    DoubleHolder(double value) {
        this.value = value;
    }
}

[TestMethod]
public void TestDebuggerValue() {
    DoubleHolder s = new DoubleHolder(12345678.12345);
    string doubleString = TestDouble.ToString();
    CultureInfo current = Thread.CurrentThread.CurrentCulture;
    Thread.CurrentThread.CurrentUICulture = current;
    CultureInfo ui = Thread.CurrentThread.CurrentUICulture;
    Debugger.Break();
}

运行该测试在调试器,当它打破了,你可以看到包含在的DoubleHolder 是格式化为作为小数分隔符。

Run that test in the debugger and, when it breaks you can see that the double contained in DoubleHolder is formatted with a . as a decimal separator.

然后关闭Visual Studio中,更改Windows的标准和格式区域选项法国,再说了,再次运行测试。你会看到 doubleString 有一个作为小数点分隔符,但调试器仍显示的DoubleHolder

Then close Visual Studio, change your windows Regional Options for Standards and Formats to French, say, and run the test again. You'll see that doubleString has a , as the decimal separator, but the the debugger still shows the double in DoubleHolder with a .

我本来希望测试在Windows操作系统上的一个适当的法文版,在法国的Visual Studio。在Visual Studio中,如果你去工具 - >选项 - >环境 - >国际设置,您可以将语言设置为同微软的Windows。默认情况下在我安装时被设置为英语。但要获得Visual Studio的法语,你需要让Windows在法国,我的版本的Windows似乎只能是英语。如果任何人有一个落地窗,或使用其他语言环境,作为小数点分隔,这将会是巨大的,如果你可以只检查是否在调试器使用作为格式化双打小数点分隔符。

I would have liked to test this on a proper French version of Windows, with Visual Studio in French. In Visual Studio, if you go to Tools -> Options -> Environment -> International Settings, you can set the Language to "Same as Microsoft Windows". By default on my installation it was set to "English". But to get Visual Studio in French you need to have Windows in French, and my version of Windows seems to be English only. If anyone has a French Windows, or any other locale that uses , as a decimal separator, it'd be great if you could just check whether the debugger uses . or , as the decimal separator in formatted doubles.

我不知道是否 Thread.CurrentThread.CurrentUICulture 可能有所作为如何在Visual Studio调试器显示的东西,我不知道该设置它像我做到上面会与在法国的完全运行Visual Studio。

I'm wondering if Thread.CurrentThread.CurrentUICulture might make a difference to how the Visual Studio debugger shows things, and I'm not sure that setting it like I do above would be the same as running Visual Studio completely in French.

不过从上面看起来像调试一贯使用作为小数点分隔符。这意味着,我认为文化无关的ToString()方法是好的,可能是preferable,如果它用于调试目的。

But from the above it does look like the debugger consistently uses . as the decimal separator. This implies to me that a culture-independent ToString() method is fine, probably preferable, if it's intended for debugging purposes.

推荐答案

有关调试你想看看调试器显示属性,不要使用的ToString()

For debugging you want to look into Debugger Display Attributes, not use ToString().

[DebuggerDisplay("{Name} [date={Date}, value={Value}]")]
public class MyClass {
    // ...
}

至于本地化中的ToString(),我会把这个机会发表意见。

As for localization of ToString(), I will pass on the opportunity to comment.