我需要使用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编辑):(
你的例子是写作的原因的完美例证
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)