声明变量并使用 TryParse 在同一行初始化它有任何问题吗?

发布于 2024-10-09 11:35:12 字数 251 浏览 5 评论 0原文

这个示例是用 C# 编写的,但我希望可以同样轻松地应用于其他示例。

我最近发现以下内容似乎工作得很好:

int i = Int32.TryParse(SomeString, out i) ? i : -1;

不知何故,变量i在技术上似乎在它出现在TryParse中时不应该被访问。或者我是否正确地假设 int i 有效地声明了变量,即使还没有语句结束?

This example is in C# but I expect could apply to others just as easily.

I recently found that the following seems to work just fine:

int i = Int32.TryParse(SomeString, out i) ? i : -1;

Somehow it seems as though the variable i shouldn't technically be accessible at the point it appears in TryParse. Or would I be correct to assume that int i effectively declares the variable, even though there is no end of statement yet?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

泪痕残 2024-10-16 11:35:12

int i 声明变量,并在 out 参数中使用它来初始化它。由于必须在结果之前评估谓词,因此 i 在使用之前声明并初始化。 (out 参数必须在返回之前分配,因此在任何情况下它都肯定会被初始化。)

也就是说,我的一些同事会因风格原因看到类似的东西而大发雷霆。 :-)

编辑: 在调查了这是如何发生的之后,我将提出一些可能的替代辅助方法。静态类的命名充当此处辅助方法的意图文档。

internal static class TryConvert
{
    /// <summary>
    /// Returns the integer result of parsing a string, or null.
    /// </summary>
    internal static int? ToNullableInt32(string toParse)
    {
        int result;
        if (Int32.TryParse(toParse, out result)) return result;
        return null;
    }

    /// <summary>
    /// Returns the integer result of parsing a string,
    /// or the supplied failure value if the parse fails.
    /// </summary>
    internal static int ToInt32(string toParse, int toReturnOnFailure)
    {
        // The nullable-result method sets up for a coalesce operator.
        return ToNullableInt32(toParse) ?? toReturnOnFailure;
    }
}

internal static class CallingCode
{
    internal static void Example(string someString)
    {
        // Name your poison. :-)
        int i = TryConvert.ToInt32(someString, -1);
        int j = TryConvert.ToNullableInt32(someString) ?? -1;

        // This avoids the issue of a sentinel value.
        int? k = TryConvert.ToNullableInt32(someString);
        if (k.HasValue)
        {
            // do something
        }
    }
}

int i declares the variable, and using it in the out parameter initializes it. Since the predicate must be evaluated before the consequent, i is therefore both declared and initialized before use. (out parameters must be assigned before returning, so it is definitely initialized in any case.)

That said, there are colleagues of mine that would throw a fit at seeing something like that on style grounds. :-)

EDIT: After surveying how this has shaken out, I'll propose a couple of possible alternative helper methods. Naming of the static class acts as intention documentation for the helper methods here.

internal static class TryConvert
{
    /// <summary>
    /// Returns the integer result of parsing a string, or null.
    /// </summary>
    internal static int? ToNullableInt32(string toParse)
    {
        int result;
        if (Int32.TryParse(toParse, out result)) return result;
        return null;
    }

    /// <summary>
    /// Returns the integer result of parsing a string,
    /// or the supplied failure value if the parse fails.
    /// </summary>
    internal static int ToInt32(string toParse, int toReturnOnFailure)
    {
        // The nullable-result method sets up for a coalesce operator.
        return ToNullableInt32(toParse) ?? toReturnOnFailure;
    }
}

internal static class CallingCode
{
    internal static void Example(string someString)
    {
        // Name your poison. :-)
        int i = TryConvert.ToInt32(someString, -1);
        int j = TryConvert.ToNullableInt32(someString) ?? -1;

        // This avoids the issue of a sentinel value.
        int? k = TryConvert.ToNullableInt32(someString);
        if (k.HasValue)
        {
            // do something
        }
    }
}
属性 2024-10-16 11:35:12

我最近发现以下似乎工作得很好

 int i = Int32.TryParse(SomeString, out i) ? i : -1;

它工作,但它并不好。

声明变量并使用 TryParse 在同一行上初始化它有任何问题吗?

是的,可读性。我认为这看起来很糟糕,而且它正在做双重工作。


您的部分问题是您希望 -1 作为默认值。 Int32.TryParse 显式定义 0 作为转换失败时的输出值。

为了便于阅读,我仍然会将其分成两行。

int i;
if (! int.TryParse(SomeString, out i))  i = -1;

当您经常需要这个时,请编写一个(静态但不是扩展)辅助方法:

int i = Utils.ParseInt(SomeString, -1);

I recently found that the following seems to work just fine

 int i = Int32.TryParse(SomeString, out i) ? i : -1;

It works, but it is not fine.

Any problem declaring a variable and using TryParse to initialize it on same line?

Yes, readability. I think this looks awful, and it is doing double work.


Part of your problem is that you want -1 as your default. Int32.TryParse explicitly defines 0 as the out value when conversion fails.

I would still break it up in 2 lines for readability's sake.

int i;
if (! int.TryParse(SomeString, out i))  i = -1;

And when you need this a lot, write a (static but not extension) helper method:

int i = Utils.ParseInt(SomeString, -1);
如果没结果 2024-10-16 11:35:12

请记住,CIL 中没有三元运算符。

int i = Int32.TryParse(SomeString, out i) ? i : -1;

您的代码将转换为代表以下 C# 代码的 CIL:

int i;
if (Int32.TryParse(SomeString, out i))
  i = i;
else
  i = -1;

这完全没问题。

Remember that there is no ternary operator in CIL.

int i = Int32.TryParse(SomeString, out i) ? i : -1;

Your code is transformed into CIL representing the following C# code:

int i;
if (Int32.TryParse(SomeString, out i))
  i = i;
else
  i = -1;

Which is perfectly fine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文