【问题标题】:Why should I use implicitly typed local variables?为什么要使用隐式类型的局部变量?
【发布时间】:2011-04-04 16:39:18
【问题描述】:

当我说

public static IMyType GetGateWayManager()
{
    IUnityContainer _container = GetContainer();
    IMyType _gateWayManager = _container.Resolve<IMyType>();
    return _gateWayManager;
}

它带有一个警告说Use implicitly types local variable。

如果我把它改成

public static IMyType GetGateWayManager()
{
    IUnityContainer _container = GetContainer();
    var _gateWayManager = _container.Resolve<IMyType>();
    return _gateWayManager;
}

没关系。

谁能告诉我为什么 VS 编辑器认为在这里使用 var 是最佳实践?

【问题讨论】:

  • 发出此警告的原因是什么?是 VS 编译器还是像 ReSharper 这样的外部工具?
  • 您说“丢失类型”这一事实表明您可以从阅读var 的文档中受益。这并不意味着“变体”。
  • 绝对看起来像 Resharper 警告...

标签: c# visual-studio resharper


【解决方案1】:

类型适用于谁?

编译器?是的,一点没错。编译器使用类型通过确保类型匹配、调用实际存在的方法并向它们传递正确类型的参数来使您的程序更有可能在运行时正确运行。在这里,编译器正在检查您是否确实返回了 IMyType 类型的内容。

编辑?再次,是的。编辑器使用后台编译和类型信息来帮助您编写代码。当你在_container 之后点击. 时,它会使用类型信息告诉你有一个Resolve 方法以及它需要什么参数。

你?没那么多。我们已经看到编译器将确保您返回 IMyType 类型的东西,那么当编译器可以为您解决并检查它时,您为什么还要关心将其声明为该类型呢?同样,编辑器会告诉你容器上的方法,那么你为什么要关心声明它是 Unity 容器还是其他类型的容器,因为你已经从变量名中知道它是某种容器,并且从编辑器,它有一个Resolve 方法。

为本地人声明类型没有问题,但是 ReSharper 告诉您的是编译器可以解决它,因此它是冗余信息,并且您的代码可以使用隐式类型和好的变量名更清晰。例如,这段代码的目的是否比原始示例更不明确?

public static IMyType GetGateWayManager()
{
    var container = GetContainer();
    var gateWayManager = container.Resolve<IMyType>();
    return gateWayManager;
}

【讨论】:

  • 隐式类型有一个优点,即如果 GetContainer 的返回类型改变(但保持相同的签名),或者因为它被重命名,或者被替换为类似的类型,上面的代码将不会不需要改变来应对。 (虽然,它必须重建)
  • 是的,好的变量名。真是个好主意。 Opacity_in_names_should_be_avoided。
【解决方案2】:

resharper 建议使用 var 而不是显式类型,因为它清晰且有用。

很清楚,因为您编写的代码较少,并且您的重点是变量名而不是类型名。您可能认为类型名称很有用,但用不了多久就会忘记它。

很有用,因为当您更改方法类型返回时,您不需要更改所有类型。

例子:

int id = getId();
List<MyType> myList = FindById(id);

在这种情况下,如果您将 id 从 int 更改为 guid,则必须在此处更改此“int”。这很小,但很容易在现实生活中的项目中变大。使用 var 你有一些编译器的代码并且不需要总是改变它。

var id = getId();
var myList = FindById(id);

我以前更喜欢显式类型,但在尝试 var 几个小时后,我就不会那么容易了。

请记住:var 在编译时更改为正确的类型。它不同于几乎在所有情况下都不推荐的动态。

【讨论】:

  • 那么看看你的第二个例子,只看 FindById 方法,返回什么类型?你看不出来,这就是隐式类型的缺点。
【解决方案3】:

可能是 ReSharper。

当变量的类型可以在代码中看到时,ReSharper 建议使用var。在您的示例中,我们可以看到_gateWayManager 的类型为IMyType,然后我们使用var 关键字来隐式键入变量。 _container 将在代码中显式输入,因为我们不能说 GetContainer() 将返回什么类型的对象

【讨论】:

    【解决方案4】:

    可能不是 VS 编辑器,而是 ReSharper 向您提供了该信息。这更多的是品味问题,而不是最佳实践。但是一旦你习惯了 var 关键字,你就会开始越来越喜欢它。至少我学会了爱它。

    【讨论】:

    • @ltsik - 不,这与手动声明类型没有什么不同。
    • @Itsik,不,它只是语法糖,将在编译时转换为正确的类型。它不是动态类型,只是一种让程序员免于写出 List>> 等的方法
    • 没有。 var 在编译时转换为正确的类型,因此行为完全相同,而 .net 4 中的 dynamic 仅在运行时检查。如果无法确定var 的类型,仍然会出现编译错误。
    • @ltsik:你可能会发现这个问题很有用stackoverflow.com/questions/3555625/…
    • 谢谢!我想我应该进入C# in Depth 的第 3 部分(我几乎完成第 2 部分)
    【解决方案5】:

    这是 Resharper 警告你,而不是 VS 编辑器。

    【讨论】:

      【解决方案6】:

      批准的答案肯定是正确的,并按照描述回答了问题。

      但是 - 我确实想提出一个您必须使用隐式类型的情况:当变量表示匿名类型时。

      考虑这段代码:

      var upperLowerWords =
          from w in words
          select new { Upper = w.ToUpper(), Lower = w.ToLower() };
      

      upperLowerWords 应该是什么类型?你不能说,因为没有 explicit 类型与返回的内容相匹配 - 但它是编译器可以识别的类型。事实上,确实如此。

      供参考:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/implicitly-typed-local-variables(这是我得到那个例子的地方)

      【讨论】:

        猜你喜欢
        • 2010-10-13
        • 1970-01-01
        • 1970-01-01
        • 2012-04-24
        • 1970-01-01
        • 1970-01-01
        • 2014-12-06
        相关资源
        最近更新 更多