You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

抛出异常后对象生命周期有多久?能否调用该对象的方法?

核心问题解答

1 异常后调用对象方法是否合法?

完全合法。你代码能正常运行也不是「GC还没销毁对象」的侥幸:GC只会回收没有任何存活强引用的对象,你的class1变量在try块外层声明,在当前方法执行结束前始终持有实例的强引用,GC无论如何都不会主动回收这个实例。

2 当前示例的可用性判断

你给出的代码逻辑是安全可用的:Calc方法的执行顺序是「先校验数据合法性→再执行计算→再写入内部存储列表」,抛出异常时,内部的calculatedPoints里存储的全是校验通过、计算完成的有效数据,状态没有被破坏,调用GetPoints获取已完成的计算结果完全符合预期。


更规范的场景适配方案

你当前的写法虽然可用,但存在隐式约定:调用方必须知道「异常抛出后还能从原对象取部分结果」,如果后续修改Calc逻辑(比如先写入列表再校验),很容易破坏状态一致性。更稳妥的实现有两种:

方案1:用返回值统一承载执行状态和结果

定义独立的结果类承载所有输出,语义明确,不需要额外约定:

// 计算结果统一返回类
public class CalcResult
{
    public List<string> CalculatedPoints { get; } = new List<string>();
    public bool IsSuccess { get; set; }
    public string ErrorMessage { get; set; }
}

// Class1的Calc方法修改为返回CalcResult
public class Class1
{
    public CalcResult Calc(string[] values)
    {
        CalcResult result = new CalcResult();
        foreach(string p in values)
        {
            if(!IsValid(p))
            {
                result.IsSuccess = false;
                result.ErrorMessage = "invalid value encountered";
                return result;
            }
            result.CalculatedPoints.Add(DoSomeCalculation(p));
        }
        result.IsSuccess = true;
        return result;
    }

    // 省略IsValid、DoSomeCalculation等辅助方法实现
}

调用方代码:

Class1 class1 = new Class1();
CalcResult calcResult = class1.Calc(arrayOfValues);
if(!calcResult.IsSuccess)
{
    LogError(calcResult.ErrorMessage);
}
Draw(calcResult.CalculatedPoints);

方案2:自定义异常携带部分计算结果

如果需要保留异常抛出的错误通知逻辑,可以自定义异常类型把已计算结果一同抛出,避免原对象残留中间状态:

// 自定义计算异常类
public class CalcFailedException : Exception
{
    public List<string> CompletedPoints { get; }
    public CalcFailedException(string message, List<string> completedPoints) : base(message)
    {
        CompletedPoints = completedPoints;
    }
}

// Class1实现修改
public class Class1
{
    private List<string> calculatedPoints = new List<string>();
    
    public void Calc(string[] values)
    {
        List<string> tempPoints = new List<string>();
        foreach(string p in values)
        {
            if(!IsValid(p))
            {
                throw new CalcFailedException("invalid value encountered", tempPoints);
            }
            tempPoints.Add(DoSomeCalculation(p));
        }
        // 全部计算成功才更新内部状态,避免残留中间结果
        calculatedPoints = tempPoints;
    }

    public List<string> GetPoints()
    {
        return calculatedPoints;
    }

    // 省略IsValid、DoSomeCalculation等辅助方法实现
}

调用方代码:

Class1 class1 = new Class1();
List<string> pointsToDraw;
try
{
    class1.Calc(arrayOfValues);
    pointsToDraw = class1.GetPoints();
}
catch (CalcFailedException e)
{
    LogError(e.Message);
    pointsToDraw = e.CompletedPoints;
}
Draw(pointsToDraw);

内容的提问来源于stack exchange,提问作者isswf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 17:15:06