在不初始化的情况下声明一个 var ...

Declare a var without initializing it... just yet

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

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
    }

或者我正在尝试做的事情的替代方案?

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

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
}

如果你需要它是全局的,因为你在 try/catch 之外使用它的一些 methods/properties,你假设它有一些接口(例如 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
}

这里的正确答案是放弃使用 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
}

作为在外部作用域中使用变量的替代方法,考虑在 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");
}    

这非常有效,例如,如果您想要 return 值(正如我在修改后的示例中指出的那样)。

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

您不能在 C# 中 "declare a var"。 var 关键字没有做任何特别的事情。它只是告诉编译器的一个快捷方式"hey, I should put a type here, but I will let you choose the type yourself because I'm lazy/I'm unsure of the type/it would be redundant with the declaration"。当你写

var i = 0;

写的完全一样

int i = 0;

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

的占位符

现在考虑这条线

var myVariable;

这里的 var 应该是什么? stringobjectintMyClassIMyInterface?编译器无法知道,所以它不允许。您必须自己填写正确的类型。

现在你的代码应该是

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
}

这将实现您想要的效果。

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

List<User> existingUsers;

在极少数情况下,您可能需要 Repo.GetAll() 的类型而不写出来,例如,如果类型的名称是具有多级泛型类型参数的不可读的混乱。在那些情况下,你可以写

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

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

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

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

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

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

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

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

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 代码也没有。

您可以改用 object,稍后分配 with/without 转换。

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