我需要使用在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编辑):(
答案 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;
}
你真的应该检查异常...