【问题标题】:Why is it not possible to declare a function with VAR return type?为什么不能声明具有 VAR 返回类型的函数?
【发布时间】:2011-05-07 03:31:22
【问题描述】:

在 C# 中,我们有 var 数据类型,但我们不能将其用作函数返回类型。
为什么这是不可能的?

public var myFunction()
{
    var = some operations
}

【问题讨论】:

  • 好吧,如果你不知道,编译器怎么知道?

标签: function c#-4.0 dynamic-data return-value return-type


【解决方案1】:

var 不是 C# 中的数据类型。这就是为什么您不能将其用作返回参数的原因。编译器在编译时从赋值的右侧推断类型,并记住在编译时已知您需要使用实际类型作为返回值。在 C# 4.0 中,您可以使用 dynamic 类型:

public dynamic myFunction()
{
    var = some operations
}

【讨论】:

  • -1,因为所提议的只是编译器应该推断出真正的返回类型是什么......使使用var 的声明等效于具有显式返回类型的相同方法声明,从方法体内的返回语句推断。这不是不可想象的——只是很复杂。请注意,根据我的答案中的示例,它已经为 lambda 表达式完成。
【解决方案2】:

我相信部分原因是编译器的设计。 Eric Lippert blogged 关于为什么 fields 不能使用隐式类型,我怀疑一些相同的论点适用于方法。

但无论如何,您很容易以模棱两可的方式结束。例如:

var Method1(bool callMethod2)
{
    return callMethod2 ? Method2() : null;
}

var Method2()
{
    return Method1(false);
}

这里的类型应该是什么?

一个更简单的例子:

var Method1(bool throwException)
{
    if (!throwException)
    {
        return Method1(true);
    }
    throw new Exception("Bang!");
}

诚然,这种模棱两可的做法完全是不允许的,但我怀疑设计团队认为设计和实现所增加的复杂性并不值得。不要忘记它们是在有限的资源下运行的——如果可以在 var 方法和 async/await 之间进行选择,我会立即选择后者。 (诚​​然,我会选择其他功能而不是 dynamic,但那是另一回事......)

请注意,返回类型推断为 lambda 表达式执行的,所以这个想法并不疯狂。例如:

IEnumerable<string> x = new[] { "x", "y", "z" };

var result = x.Select(s => { return s.Length; }); // Long form

当编译器对Select 执行重载解析时,编译器会推断出lambda 表达式的完整类型,并将其转换为Func&lt;string, int&gt;。将相同的想法应用于方法并非不可想象 - 只是复杂。

【讨论】:

  • 您的分析一如既往地准确。正确执行此功能需要整个程序分析,这对编译器具有重大的架构和性能影响。此外,“字段上没有 var”的所有原因都适用。例如,我们没有标准化的方式来表示公共 API 中的匿名类型。如果您想要一种能够提供这种类型推断的语言,请尝试 F#。
猜你喜欢
  • 1970-01-01
  • 2017-03-02
  • 2020-08-23
  • 1970-01-01
  • 2021-11-06
  • 1970-01-01
  • 1970-01-01
  • 2019-03-04
  • 1970-01-01
相关资源
最近更新 更多