Наткнулся на любопытный момент в исходниках CoreCLR. В простейшем листинге
int.TryParse первой инструкцией идет валидация стиля, а уже потом проверка значения на null.
public static bool TryParse([NotNullWhen(true)] string? s, NumberStyles style, IFormatProvider? provider, out int result)
{
NumberFormatInfo.ValidateParseStyleInteger(style);
if (s is null)
{
result = 0;
return false;
}
return Number.TryParseBinaryInteger(s.AsSpan(), style, NumberFormatInfo.GetInstance(provider), out result) == Number.ParsingStatus.OK;
}
Какие цели при этом приследуются, и не лучше ли перенести валидацию после проверки строки? Мы же можем сэкономить некоторое (пусть небольшое) процессорное время? Все что делает валидация стиля это
проверяет соответствующие флаги
.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void ValidateParseStyleInteger(NumberStyles style)
{
// Check for undefined flags or using AllowHexSpecifier/AllowBinarySpecifier each with anything other than AllowLeadingWhite/AllowTrailingWhite.
if ((style & (InvalidNumberStyles | NumberStyles.AllowHexSpecifier | NumberStyles.AllowBinarySpecifier)) != 0 &&
(style & ~NumberStyles.HexNumber) != 0 &&
(style & ~NumberStyles.BinaryNumber) != 0)
{
ThrowInvalid(style);
static void ThrowInvalid(NumberStyles value)
{
throw new ArgumentException(
(value & InvalidNumberStyles) != 0 ? SR.Argument_InvalidNumberStyles : SR.Arg_InvalidHexBinaryStyle,
nameof(style));
}
}
}
Это как-то связано с атрибутом для статического анализа NotNullWhen?