在Try-Catch外部使用变量

Kai*_*kus -2 c#

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

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

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

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

任何方式让ALLWAYS留住客户?:)

编辑:

如你所料,这是伪代码.我可以阅读,看起来在构造函数中使用异常是一个不好的想法.这是我的构造函数的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")
    } 
} 
Run Code Online (Sandbox Code Playgroud)

在方法'TheProvided ...'中,我检查参数是否与列表中值的总和一致.如果没有,我更新它们并通过引发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) { }
    }
Run Code Online (Sandbox Code Playgroud)

但我可以,在'try'块之外断言directDebitRemmitanceReject.ControlSum

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

谢谢!:)

(抱歉EXTENSIVE编辑):(

das*_*ght 7

你的例子是写作的原因的完美例证

catch (Exception){}
Run Code Online (Sandbox Code Playgroud)

是一个非常糟糕的做法.

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

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

try {
    ...
} catch (Exception) {
    customer = Customer.Unknown;
}
Run Code Online (Sandbox Code Playgroud)

这假定Customer具有某种Unknown类型的属性Customer具有某些默认行为.

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

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

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

class CustomerFactory {
    public CustomerCreationResult CreateCustomer(String name, int age) { ... }
}
Run Code Online (Sandbox Code Playgroud)

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

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