#c# #string-interpolation
#c# #строка-интерполяция
Вопрос:
У меня есть *.resx
строка, которая выглядит следующим образом:
Failed to deserialize an object of type '{0}' from the following string:{1}{2}
Эта строка используется для регистрации таких ошибок, и в настоящее время оператор протоколирования выглядит следующим образом:
_logger.LogError(Resources.FailedToDeserialize, typeof(MyType).Name, Environment.NewLine, invalidJsonString);
Как вы можете видеть — мне нужно проходить Environment.NewLine
каждый раз, чтобы правильно отображать мои журналы для любой ОС.
Мне любопытно, есть ли какие-либо зарезервированные слова / символы интерполяции строк для вставки таких значений?
Например, моя строка может выглядеть так:
Failed to deserialize an object of type '{0}' from the following string:{NewLine}{2}
И мое заявление о регистрации было бы немного проще:
_logger.LogError(Resources.FailedToDeserialize, typeof(MyType).Name, invalidJsonString);
Комментарии:
1. В редакторе ресурсов Visual Studio вы можете использовать
Shift
Return
для вставки разрыва строки внутри значения. Но при этом будет использоваться символ новой строки из вашей текущей ОС, а не ОС, на которой в конечном итоге работает ваше приложение.2. Кроме того, интерполяция строк — это нечто совершенно иное, чем код, который вы используете в своем вопросе.
3. Одна вещь, которую вы можете сделать, это некоторая форма предварительной обработки при запуске приложения, прочитав файл ресурсов, заменив выбранное вами ключевое слово, т.е.
{NewLine}
НаEnvironment.NewLine
, а затем используйте эту кэшированную строку на протяжении всего срока службы вашего приложения.4. Итак, у вас есть строка json, которая не прошла десериализацию. Есть ли вероятность появления в этой строке какого-то странного символа, который испортит форматирование используемой библиотеки журналов?
5. @RichardDeeming, думаю, ты прав. Я изменю заголовок.
Ответ №1:
Одна вещь, которую вы можете сделать, это некоторая форма предварительной обработки при запуске приложения, прочитав файл ресурсов, заменив выбранное вами ключевое слово, т.е. {NewLine}
На Environment.NewLine
, а затем используйте эту кэшированную строку на протяжении всего срока службы вашего приложения.
Вы можете создать поля readonly
и выполнить некоторую магию отражения, чтобы установить значение, но этот пример должен дать вам представление о том, как решить вашу текущую проблему.
public static class LoggingMessageTemplates
{
//Reference your resource here e.g Resource.FailedToDeserialize
public static string FailedToDeserialize = "Resource.Something {NewLine} Something Else";
public static void FormatMessages()
{
var stringFields = typeof(LoggingMessageTemplates)
.GetFields()
.Where(x => x.FieldType == typeof(string));
foreach(var field in stringFields)
{
if (field.GetValue(null) is not string fieldValue)
{
throw new InvalidCastException($"Failed to cast field {field.Name} to string.");
}
field.SetValue(null, fieldValue.Replace("{NewLine}", Environment.NewLine));
}
}
}
//On application startup, format the resources to use the Environment.NewLine char of the current system.
LoggingMessageTemplates.FormatMessages();
//When logging, reference the LoggingMessageTemplates class rather than the direct resource.
Console.WriteLine(LoggingMessageTemplates.FailedToDeserialize);
//i.e
_logger.LogError(LoggingMessageTemplates.FailedToDeserialize, typeof(MyType).Name, invalidJsonString);