我怎样才能重写这段代码,以免看起来好像我正在使用异常作为流程控制的一种形式?
How could I rework this code so as not to appear as if I am using exceptions as a form of flow-control?
我听说异常和 try-catch 块不应该用于流控制,所以我想要一种方法来重写这段代码以避免出现这种情况。
我在 neuralNetwork class 中有一个方法 validateTrainingSets,它确实如其名称所暗示的那样 - 验证提供的训练集(除其他事项外,确保训练集中的输入数量匹配神经网络的输入数量,以及每个答案的输出数量与神经网络的最终输出数量匹配)。
因为验证失败的方式有很多种,我决定将抛出异常留给验证方法本身,函数可以抛出三种不同的自定义异常。
在允许 class 用户手动更新每层神经元数量的方法中,代码的最后一位验证 and/or 更新训练集(取决于是否有新的提供了训练集),我的问题是,我将如何改进它?
在下面的代码中,验证器中的 "true" 参数告诉验证器如果失败则将训练集设置为空。 (本意是如果用户没有提供新的训练集,但已有的训练集与新的排列一致则保留,否则丢弃)。
fldValidate 字段是一个标志,在代码的前面部分被设置为 false,我需要确保它被设置回 true,不考虑任何错误。
try { validateTrainingSets(fldTrainingSets, fldTrainingAnswers, true); }
catch(TrainingSetCardinalityMismatch) { }
catch(InputSetCardinlityMismatch) { }
catch(OutputAnswerCardinalityMismatch) { }
catch {
fldValidate = true;
throw;
}
finally { fldValidate = true; }
是的,我认为大多数审阅者会觉得这令人困惑并要求进行更改。如果我对问题的理解正确,您可以使用 enum
例如:
enum Validity { Valid, TrainingSetCardinalityMismatch, InputSetCardinalityMismatch, OutputAnswerCardinalityMismatch }
class TrainingSet {
Validity Validate(TrainingAnswer[] trainingAnswers) { // ... etc ... }
}
然后按照您认为最直观的方式进行分配,例如:
var validTrainingSets =
from trainingSet in fldTrainingSets
where trainingSet.Validate(fldTrainingSets) == Validity.Valid
select trainingSet;
或:
var validTrainingSets =
fldTrainingSelects.Select(t => t.Validate(fldTrainingAnswers)).Filter(v => v == Validity.Valid);
或:
Dictionary<Validity, List<TrainingSet>> groupedTrainingSets =
from trainingSet in fldTrainingSets
group trainingSet by trainingSet.Validate(fldTrainingAnswers) into validityGroup
select new { validityGroup.Key, validityGroup.ToList() }
如果 enum
还不够,请尝试接口或抽象 class :
interface IValidity {}
class Valid : IValidity { // ... etc ... }
class TrainingSetCardinalityMismatch : IValidity { public int ExpectedCardinality; // etc... }
我听说异常和 try-catch 块不应该用于流控制,所以我想要一种方法来重写这段代码以避免出现这种情况。
我在 neuralNetwork class 中有一个方法 validateTrainingSets,它确实如其名称所暗示的那样 - 验证提供的训练集(除其他事项外,确保训练集中的输入数量匹配神经网络的输入数量,以及每个答案的输出数量与神经网络的最终输出数量匹配)。
因为验证失败的方式有很多种,我决定将抛出异常留给验证方法本身,函数可以抛出三种不同的自定义异常。
在允许 class 用户手动更新每层神经元数量的方法中,代码的最后一位验证 and/or 更新训练集(取决于是否有新的提供了训练集),我的问题是,我将如何改进它?
在下面的代码中,验证器中的 "true" 参数告诉验证器如果失败则将训练集设置为空。 (本意是如果用户没有提供新的训练集,但已有的训练集与新的排列一致则保留,否则丢弃)。
fldValidate 字段是一个标志,在代码的前面部分被设置为 false,我需要确保它被设置回 true,不考虑任何错误。
try { validateTrainingSets(fldTrainingSets, fldTrainingAnswers, true); }
catch(TrainingSetCardinalityMismatch) { }
catch(InputSetCardinlityMismatch) { }
catch(OutputAnswerCardinalityMismatch) { }
catch {
fldValidate = true;
throw;
}
finally { fldValidate = true; }
是的,我认为大多数审阅者会觉得这令人困惑并要求进行更改。如果我对问题的理解正确,您可以使用 enum
例如:
enum Validity { Valid, TrainingSetCardinalityMismatch, InputSetCardinalityMismatch, OutputAnswerCardinalityMismatch }
class TrainingSet {
Validity Validate(TrainingAnswer[] trainingAnswers) { // ... etc ... }
}
然后按照您认为最直观的方式进行分配,例如:
var validTrainingSets =
from trainingSet in fldTrainingSets
where trainingSet.Validate(fldTrainingSets) == Validity.Valid
select trainingSet;
或:
var validTrainingSets =
fldTrainingSelects.Select(t => t.Validate(fldTrainingAnswers)).Filter(v => v == Validity.Valid);
或:
Dictionary<Validity, List<TrainingSet>> groupedTrainingSets =
from trainingSet in fldTrainingSets
group trainingSet by trainingSet.Validate(fldTrainingAnswers) into validityGroup
select new { validityGroup.Key, validityGroup.ToList() }
如果 enum
还不够,请尝试接口或抽象 class :
interface IValidity {}
class Valid : IValidity { // ... etc ... }
class TrainingSetCardinalityMismatch : IValidity { public int ExpectedCardinality; // etc... }