在Try-Catch外部使用变量

时间:2015-12-31 13:25:27

标签: c#

我需要使用在try块中初始化的变量的值。我有这个基本代码

Customer customer = null;
try
{
    customer = new Customer(....);
}
catch (Exception){}
string customerCode = customer.Code;

如果没有例外,则客户完全可用,但如果有例外,客户未初始化,则返回null

我已检查过客户ALLWAYS在块内正确初始化。 INSIDE即使在例外情况下也完全可以使用。但我需要它以供以后使用。

任何方式让ALLWAY保持客户? :)

修改

如你所料,这是伪代码。我可以阅读,看起来在构造函数中使用异常是一个不好的想法。这是我构造函数的REAL代码的一部分。

public class DirectDebitRemmitanceReject
{
    int numberOfTransactions;
    decimal controlSum;
    List<DirectDebitTransactionReject> directDebitTransactionRejects;

    public DirectDebitRemmitanceReject(
        int numberOfTransactions,
        decimal controlSum, 
        List<DirectDebitTransactionReject> directDebitTransactionRejects)
    {
        this.numberOfTransactions = numberOfTransactions;
        this.controlSum = controlSum;
        this.directDebitTransactionRejects = directDebitTransactionRejects;

        if (TheProvidedNumberOfTransactionsIsWrong()) ChangeNumberOfTransactionsAndRiseException();
        if (TheProvidedControlSumIsWrong()) ChangeControlSumAndRiseException();
    }

    private bool TheProvidedNumberOfTransactionsIsWrong()
    {
        return (numberOfTransactions != directDebitTransactionRejects.Count)
    }

    private bool TheProvidedControlSumIsWrong()
    {
        return (controlSum !=directDebitTransactionRejects.Select(ddRemmitanceReject => ddRemmitanceReject.Amount).Sum();)
    }

    private void ChangeNumberOfTransactionsAndRiseException()
    {
        ......
        ......
        throw new ArgumentException(exceptionMessage, "numberOfTransactions")

    private void ChangeControlSumAndRiseException()
    {
        ......
        ......
        throw new ArgumentException(exceptionMessage, "controlSum")
    } 
} 

在方法中提供......&#39;我检查参数是否与列表中的值之和一致。如果没有,我更新它们并通过引发ArgumentException

来通知

事实是,我希望构造函数ALLWAYS返回一个有效的(全等)DirectDebitRemmitanceReject,但是如果提供了错误的numberOfTransactions或controlSum,则需要相同的构造函数来引发异常。 NumberOfTransactions和controlSum不应该在以后修改,只能重新编译。

在我的测试中,这很好用

    [TestMethod]
    [ExpectedException(typeof(System.ArgumentException))]
    public void IfTheProvidedControlSumInARemmitanceRejectIsWorgAnExceptionIsThrown()
    {
        try
        {
            DirectDebitRemmitanceReject directDebitRemmitanceReject = new DirectDebitRemmitanceReject(
                originalDirectDebitRemmitance1MessageID,
                2,
                100,
                directDebitTransactionRejectsList1);
        }
        catch (System.ArgumentException e)
        {
            Assert.AreEqual("controlSum", e.ParamName);
            Assert.AreEqual("The Control Sum is wrong. Provided: 100. Expected: 150. Initialized with expected value", e.GetMessageWithoutParamName());
            throw;
        }
    }

    [TestMethod]
    public void IfTheProvidedControlSumInARemmitanceRejectIsWorgItIsCorrected()
    {
        try
        {
            DirectDebitRemmitanceReject directDebitRemmitanceReject = new DirectDebitRemmitanceReject(
                originalDirectDebitRemmitance1MessageID,
                2,
                100,
                directDebitTransactionRejectsList1);
            Assert.AreEqual(150, directDebitRemmitanceReject.ControlSum);
        }
        catch (ArgumentException) { }
    }

但我可以,在“尝试”之外断言directDebitRemmitanceReject.ControlSum。块

那么......我是否尝试了另一种方法(从构造函数中删除异常)还是有另一种解决方法?

谢谢! :)

(对不起,EXTENSIVE编辑):(

3 个答案:

答案 0 :(得分:7)

你的例子是写作

的完美例证
catch (Exception){}

是一种非常糟糕的做法。

当你发现异常时,你应该对此做些什么。如果您不知道如何处理代码的特定方法中的异常,请不要在该方法中捕获异常。

如果您总是需要客户,即使其检索导致异常,也可以在catch块中添加一些代码,将customer变量设置为某个默认对象:

try {
    ...
} catch (Exception) {
    customer = Customer.Unknown;
}

这假设Customer具有Unknown类型的属性Customer,但有一些默认行为。

  

评论:需要警告我的代码的上一级。只是,当我创建一个实例时,创建它,但警告错误的参数。你能推荐一些更好的方法吗?

创建工厂以在创建用户时验证用户:

class CustomerCreationResult {
    public Customer Customer() { get; set; }
    public CustomerCreationError Error() { get; set; }
}

class CustomerFactory {
    public CustomerCreationResult CreateCustomer(String name, int age) { ... }
}

现在您可以按如下方式创建客户:

var r = myCustomerFactory.CreateCustomer(name, age);
if (r.getError() != null) {
    ... // Present the error
}
Customer customer = r.Customer;
...

答案 1 :(得分:0)

如果客户始终正确初始化,那么为什么在try块中有它?

如果要在发生异常时保留它,请将客户端的初始化移到try块之外,或者将try / catch用于较小的代码块。

例如:

Customer customer = null;
try
{
    //in this block do the stuff that is unlikely to cause exceptions
    customer = new Customer(...);

    try
    {
         //stuff that is likely to cause exceptions
    }
    catch(Exception e)
    {
         //handle likely errors
    }
catch (Exception e)
{
    //handle the unusual errors
}

答案 2 :(得分:-1)

我认为&#39; dasblinkenlight的回答非常好,但出于最简单的目的,if就足够了:

string customerCode = "";
if (customer!=null)
{
    customerCode = customer.Code;
}

你真的应该检查异常...