【问题标题】:Declare a var without initializing it... just yet声明一个 var 而不初始化它......
【发布时间】:2015-04-27 08:25:33
【问题描述】:

有没有办法或技巧来做类似的事情:

var existingUsers; // This is not possible, but i need it to be global :)
try
{
    existingUsers = Repo.GetAll(); // This may crash, and needs to be in a try
}
catch (Exception)
{
    throw new Exception("some error, don't bother");
}

if (existingUsers.Count > 0)
    {
        //some code
    }

或者也许可以替代我正在尝试做的事情?

【问题讨论】:

  • 你为什么不明确声明它的强类型呢?
  • 如果你需要它是全局的,因为你在 try/catch 之外使用了它的一些方法/属性,你假设它有一些接口。将var 替换为ISomeInterface,比如ICollection 可能吗?
  • @VivekGupta - 您不能将无类型变量声明为 null
  • 我如何对 cme​​ts 投反对票? @vivekGupta 看着你
  • 你想完成什么?这篇文章花费了你足够多的按键来输入实际类型,而不是 var 在今年剩下的时间里。

标签: c# .net var


【解决方案1】:

您必须在声明变量时指定类型 - 显式或推断。但是你可以做到接近你想要的:

var existingUsers = (List<User>)null;
try
{
    existingUsers = Repo.GetAll();
}
catch (Exception)
{
    throw new Exception("some error, don't bother");
}
if (existingUsers.Count() > 0)
{
    //some code
}

【讨论】:

  • 您不需要这样做,只需将var 替换为类型:List&lt;User&gt; existingUsers = null。并从 try..catch 内部删除 var
  • 您甚至可以省略= nullList&lt;User&gt; existingUsers; 也可以。它不需要初始化,因为它的值在分配之前没有被使用。
  • @Jamiec - 是的,我很感激。 OP 从他想要一个var 的想法开始 - 我只是保留了这个主题。我知道var x = 语法,但不知道List&lt;User&gt; x = 语法,这将是非常奇怪的,你不觉得吗?
  • @hvd - 如果我想保留varnull 是必需的。
  • @Jamiec - 很好地抓住了try 中的var - 我确实错过了。 :-)
【解决方案2】:

如果你需要它是全局的,因为你在 try/catch 之外使用了它的一些方法/属性,你假设它有一些接口(例如ICollection):

ICollection existingUsers; 
try
{
    existingUsers = Repo.GetAll(); // This may crash, and needs to be in a try
}
catch (Exception)
{
    throw new Exception("some error, don't bother");
}  
if (existingUsers.Count > 0)
{
    //some code
}

【讨论】:

    【解决方案3】:

    这里的正确答案是放弃var的使用,并在try...catch块之外正确指定existingUsers的类型:

    List<User> existingUsers = null; // or whatever is the right type!
    try
    {
        existingUsers = Repo.GetAll(); // This may crash, and needs to be in a try
    }
    catch (Exception)
    {
        throw new Exception("some error, don't bother");
    }
    if (existingUsers.Count > 0)
    {
        //some code
    }
    

    【讨论】:

    • 谢谢你,这是完美的:)
    【解决方案4】:

    作为将变量放在外部范围内的替代方法,请考虑在 try 块内进行所有处理:

    try
    {
        var existingUsers = Repo.GetAll(); // This may crash, and needs to be in a try
        if (existingUsers.Count > 0)
        {
          // Some code
        }
    
        return existingUsers;
    }
    catch (Exception)
    {
        throw new Exception("some error, don't bother");
    }    
    

    这很有效,例如,如果您想返回值(正如我在修改示例中指出的那样)。

    我还建议捕获一个特定的异常(例如 RepositoryOperationFailedException),以将此情况与您的“某些代码”失败的情况区分开来。

    【讨论】:

      【解决方案5】:

      您不能在 C# 中“声明 var”。 var 关键字没有做任何特别的事情。这只是告诉编译器“嘿,我应该在这里放一个类型,但我会让你自己选择类型,因为我很懒/我不确定类型/声明会是多余的”的捷径。当你写

      var i = 0;
      

      和写的一模一样

      int i = 0;
      

      如果您在大多数 IDE 中将鼠标放在 var 上,智能感知会告诉您它只是 ìnt 的占位符。

      现在考虑这条线

      var myVariable;
      

      var 应该是什么? string, object, int, MyClass, IMyInterface?编译器没有办法知道,所以它不能允许。您必须自己填写正确的类型。

      现在你的代码应该是

      List<User> existingUsers; // This is not possible, but i need it to be global :)
      try
      {
          existingUsers = Repo.GetAll(); // This may crash, and needs to be in a try
      }
      catch (Exception)
      {
          throw new Exception("some error, don't bother");
      }
      
      if (existingUsers.Count > 0)
      {
          //some code
      }
      

      这将完全实现您想要的。

      【讨论】:

        【解决方案6】:

        如前所述,如果您知道需要 existingUsers 的具体类型,您可以将 existingUsers 声明为该类型。

        List<User> existingUsers;
        

        在极少数情况下,您可能需要Repo.GetAll() 的类型而不将其写出来,例如,如果类型的名称与多个级别的泛型类型参数一起难以阅读。在这些情况下,您可以编写

        var existingUsers = true ? null : Repo.GetAll();
        

        但请在您绝对没有其他选择的情况下这样做,并添加说明您这样做的原因的评论。

        【讨论】:

        • 我没有看到任何情况下你必须求助于这个(我一开始以为是匿名类型,但方法的签名中不能有匿名类型,所以就这样了)。你有一个例子吗?
        • @Falanwe “必须”有点强,但在设计不佳的函数返回类(如 SortedDictionary&lt;int, SortedDictionary&lt;int, Dictionary&lt;Tuple&lt;DateTime, DateTime&gt;, Tuple&lt;int, string&gt;&gt;&gt;&gt;)中,不写出该类型更具可读性。
        • @Falanwe 方法可以返回匿名类型,顺便说一句,如果返回类型是也出现在参数中的泛型类型参数。 var x = true ? null : new { i = 1 }; x = new[] { new { i = 1 }, new { i = 2 } }.First();(未经测试,但思路应该很清楚)。
        • 谢谢!我没有想到匿名泛型类型。
        【解决方案7】:

        这就是dynamic 的用途:只需在您的代码中将var 替换为dynamic

        但请注意,您放弃了类型安全!

        编辑:给出批准的答案和 cmets: 是的,我知道这是一种相当丑陋的方式,我承认我没有完全理解这个问题的真正要求。

        【讨论】:

        • dynamicvar 无关。它们是完全不同的野兽,用途截然不同。我不会让任何人考虑在我的代码库附近用dynamic 替换var
        【解决方案8】:

        我知道这个问题的答案已经被接受了,但我想在讨论中添加一些东西......

        在编写 try/catch 逻辑时,有时我发现将 try/catch 逻辑与使用逻辑分开会更清晰。

        对于您的示例,我可能会编写一个处理 try/catch 逻辑的 tryGetExistingUsers() 方法:

        private List<User> tryGetExistingUsers() // Cannot return null
        {
            try
            {
                var existingUsers = Repo.GetAll(); 
        
                if (existingUsers == null)
                    throw new InvalidOperationException("List of existing users is null.");
        
                return existingUsers;
            }
        
            catch (Exception exception)
            {
                throw new Exception("some error, don't bother", exception);
            }
        }
        

        那我就这样称呼它:

        var existingUsers = tryGetExistingUsers();
        
        if (existingUsers.Count > 0)
        {
            // Some code.
        }
        

        那么主逻辑就不会被try/catch逻辑污染了。当然,这并没有显示处理重新抛出的异常的位置;但OP代码也没有。

        【讨论】:

          【解决方案9】:

          您可以改用object,并在以后使用/不使用强制转换的情况下分配它。

                      object var1;
                      switch (v)
                      {
                          case 1:
                              var1 = "String";
                              break;
                          case 2:
                              var1 = 2;
                              break;
                          default:
                              break;
                      }
          

          【讨论】:

            猜你喜欢
            • 2021-10-28
            • 1970-01-01
            • 2020-05-09
            • 1970-01-01
            • 1970-01-01
            • 2016-02-02
            • 1970-01-01
            • 2015-04-05
            • 1970-01-01
            相关资源
            最近更新 更多