Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么';我的C#编译器(VisualStudio)是否允许我使用try块来执行此操作?_C#_Visual Studio 2013 - Fatal编程技术网

为什么';我的C#编译器(VisualStudio)是否允许我使用try块来执行此操作?

为什么';我的C#编译器(VisualStudio)是否允许我使用try块来执行此操作?,c#,visual-studio-2013,C#,Visual Studio 2013,我在开发过程中有很多场景,我想做一些事情,比如 try { long presult = EvalInner(eqtn,new Tuple<int, int>(++begidx,curidx-1),eqtnArgs); } catch ( Exception e ) { throw e; } result = evalNewResult(result,lastop,presult,ref negateNextNum,ref negateNextOp);

我在开发过程中有很多场景,我想做一些事情,比如

try 
{ 
    long presult = EvalInner(eqtn,new Tuple<int, int>(++begidx,curidx-1),eqtnArgs); 
}
catch ( Exception e ) 
{ 
    throw e; 
}
result = evalNewResult(result,lastop,presult,ref negateNextNum,ref negateNextOp); 
// ...
return presult;

当前上下文中不存在名称“presult”

如果它是智能的,它会理解
presult
要么在
try
块中初始化,要么在使用
presult
之前退出该过程

可能的解决办法(没有一个是好的):

  • 声明
    长预设就在
    try
    语句之前。这使编译器非常生气,因为它错误地认为有可能返回未初始化的变量
  • 使用
    long presult=default(long)
    初始化它。这是可行的,但这是一种糟糕的做法,因为阅读代码的人不知道将其初始化为默认值是否可以解决1中描述的问题。或者是因为值
    presult
    ,因为设置为默认值
    long
    在程序上下文中具有某种实际意义
  • long初始化它?presult=null
    。这在语义上更好,因为很明显它的意思是“presult在这一点上没有任何价值”,而在2。读者必须明白预设有一个毫无意义的价值。这里的问题是,
    null
    ify一个值不仅需要额外的内存,但随后我必须更改函数
    EvalInner
    以返回
    long?
    ,这导致一系列需要将更多
    long
    s更改为
    long?
    s,我的程序最终被
    null
    指定的变量打乱;这是一个完全混乱的问号哈哈
  • 无论如何,我应该如何处理这样的案件呢?

    怎么样:

    try 
    { 
        long presult = EvalInner(eqtn,new Tuple<int, int>(++begidx,curidx-1),eqtnArgs); 
        result = evalNewResult(result,lastop,presult,ref negateNextNum,ref negateNextOp); 
        // ...
        return presult;
    }
    catch ( Exception e ) 
    { 
        //Do some useful logging
        throw; //Don't lose stacktrace!
    }
    
    试试看
    { 
    long presult=EvalInner(eqtn,新元组(++begidx,curidx-1),eqtnArgs);
    结果=evalNewResult(结果、lastop、presult、ref negateNextNum、ref negateNextOp);
    // ...
    回归预设;
    }
    捕获(例外e)
    { 
    //做一些有用的日志记录
    抛出;//不要丢失stacktrace!
    }
    
    我不理解你的问题。调用
    evalNewResult
    时,编译器无法知道
    presult
    的值,因此需要在try块之外声明它。这是C#和许多其他语言中作用域的一般规则

    解决方案是在try块之前声明并初始化它。问题是“在发生异常时,预设的值应该是什么”。编译器无法自行提出此问题。

    请检查此问题以获得更多启示

    编译器的工作是生成代码,管理由该程序操作的数据的存储。有很多不同的生成代码来管理内存的方法,但随着时间的推移,两种基本技术已经根深蒂固

    第一种是要有某种“长寿命”存储区域,其中存储中每个字节的“生存期”——即它与某个程序变量有效关联的时间段——不能轻易提前预测。编译器生成对“堆管理器”的调用,该“堆管理器”知道如何在需要时动态分配存储,并在不再需要时回收存储

    第二种是具有某种“短寿命”存储区域,其中存储中每个字节的生存期是众所周知的,特别是存储的生存期遵循“嵌套”模式。也就是说,短周期变量中最长周期变量的分配与随后的短周期变量的分配严格重叠

    局部变量遵循后一种模式;当一个方法被输入时,它的局部变量就活跃了。当该方法调用另一个方法时,新方法的局部变量会激活。在第一个方法的局部变量死之前,它们就死了。可以提前计算出与局部变量相关的存储的生命周期的开始和结束的相对顺序

    由于这个原因,局部变量通常被生成为“堆栈”数据结构上的存储,因为堆栈具有这样一个属性,即推到堆栈上的第一个对象将是最后弹出的对象


    所以整体局部变量的寿命很短,通常存储在堆栈中,为什么堆栈比其他堆栈更有效呢。有关为什么堆叠的更多信息,我将逐一介绍您的观点:

  • 宣布长期预设;就在try语句之前。这使得 编译器疯了,因为它错误地认为有可能 返回未初始化的变量
  • 实际上,编译器正确地确定有可能返回未初始化的变量。由于变量仅在右侧的函数成功时设置,并且由于您在try..catch块中有它,因此函数可能会抛出而不返回,因此不会初始化变量。编译器没有足够聪明地看到,您正在捕获顶级异常并抛出(以一种糟糕的方式,丢失堆栈跟踪),而它应该不会到达返回。但是,有一些方法可以绕过它(主要是在调试期间通过拖动执行光标)

  • 使用long presult=default(long)初始化它。这是可行的,但是 这是一种糟糕的做法,因为阅读代码的人不知道 是否将其初始化为默认值是为了解决 1中描述的问题。或者是因为该值是因为集合而预设的 默认long在上下文中有一些真正的意义 节目
  • 由于像
    long
    int
    short
    这样的值类型必须有一个值,这是一种不错的做法。如果要将它们表示为没有值,请使用这些类型的可空版本(即
    long?presult=n)
    
    try 
    { 
        long presult = EvalInner(eqtn,new Tuple<int, int>(++begidx,curidx-1),eqtnArgs); 
        result = evalNewResult(result,lastop,presult,ref negateNextNum,ref negateNextOp); 
        // ...
        return presult;
    }
    catch ( Exception e ) 
    { 
        //Do some useful logging
        throw; //Don't lose stacktrace!
    }
    
    using System;
    
    namespace app1
    {
        class Program
        {
            static void Main(string[] args)
            {
                Presult();
            }
    
            private static long Presult()
            {
                long presult;
                try
                {
                    object eqtn = null;
                    char begidx = '\0';
                    int curidx = 0;
                    object eqtnArgs = null;
                    presult = EvalInner(eqtn, new Tuple<int, int>(++begidx, curidx - 1), eqtnArgs);
                }
                catch (Exception e)
                {
                    throw e;
                }
                int result = 0;
                object lastop = null;
                object negateNextNum = null;
                object negateNextOp = null;
                result = evalNewResult(result, lastop, presult, ref negateNextNum, ref negateNextOp);
                // ...
                return presult;
            }
    
            private static int evalNewResult(int result, object lastop, long presult, ref object negateNextNum, ref object negateNextOp)
            {
                return 0;
            }
    
            private static long EvalInner(object eqtn, Tuple<int, int> tuple, object eqtnArgs)
            {
                return 0;
            }
        }
    }