Try pattern vs throwing exceptions for expected failures in C#
Return bool from a TryX method when failure is an ordinary outcome the caller will branch on, and throw when it is a bug or a broken precondition. Measured on .NET 10.0.10: a failed int.TryParse costs 4.9 ns, a caught FormatException costs 2,487 ns.