在参数列表中声明变量

declare variables in argument list

在 c# 7 中可以为参数列表中的 out 个变量声明变量:

if (int.TryParse(input, out int result))
    WriteLine(result);

是否可以在参数列表中声明 ("non out") 变量?像这样:

if (!string.IsNullOrEmpty(string result=FuncGetStr()))
        WriteLine(result);

您可以在语句中赋值变量,但是变量的声明应该在它们之外完成。您不能将它们组合在一起(在 out 和模式匹配之外,正如您在问题中已经指出的那样)。

bool b;
string a;

if (b = string.IsNullOrEmpty(a = "a")){ }

关于 为什么 这种行为与 out 不同,等等,Damien_The_Unbeliever 的评论可能很有趣:

The ability to declare out variables inline arises from the awkwardness that it a) has to be a variable rather than a value and b) there's often nothing too useful to do with the value if you declare it before the function is called. I don't see the same motivations for other such uses.

你不能在参数列表中这样做,不行。

可以为此使用模式匹配,但我不建议这样做:

if (FuncGetStr() is string result && !string.IsNullOrEmpty(result))

这将声明保留在 if 的源代码中,但是 result 的范围仍然是封闭块,所以我认为将其分开会简单得多:

// Mostly equivalent, and easier to read
string result = FuncGetStr();
if (!string.IsNullOrEmpty(result))
{
    ...
}

我能想到的有两个区别:

  • result在第一个版本if语句之后没有明确赋值
  • string.IsNullOrEmpty 如果 FuncGetStr() returns 为 null,则在第一个版本中甚至不会调用,因为 is 模式将不匹配。你可以因此写成:

    if (FuncGetStr() is string result && result != "")
    

太可怕了,你 可以 做到这一点,用一个辅助方法让你使用 out 参数。这是一个完整的例子。请注意,我不是建议这样做。

// EVIL CODE: DO NOT USE
using System;

public class Test
{
    static void Main(string[] args)
    {
        if (!string.IsNullOrEmpty(Call(FuncGetStr, out string result)))
        {
            Console.WriteLine(result);
        }
    }

    static string FuncGetStr() => "foo";

    static T Call<T>(Func<T> func, out T x) => x = func();
}