我有多种方法,输入参数不同,输出相同。
我使用输入类型的数字调用Method1,然后检查其结果,如果结果有效则调用下一个方法(此时输入类型为字符串),依此类推。
在这个例子中,我有三种方法,但如果我有10种方法或20种方法,不同的输入和相同的输出,我必须写冗余代码,我该如何防止这些冗余代码?
这是方法的示例:
public ValidationResult Method1(int number, string family)
{
var validationResult = new validationResult();
if(number > 10 || family="akbari")
{
validationResult.Errors.Add(new ValidationFailure("", "Invalid Number"));
}
return validationResult;
}
public ValidationResult Method1(string name)
{
var validationResult = new validationResult();
if(name.Length > 20)
{
validationResult.Errors.Add(new ValidationFailure("", "Invalid name"));
}
return validationResult;
}
public ValidationResult Method1(double average, string family)
{
var validationResult = new validationResult();
if(average < 14)
{
validationResult.Errors.Add(new ValidationFailure("", "Invalid average"));
}
return validationResult;
}
我称之为以下方法:
var validationResult = Method1(20, "test");
if (!validationResult.IsValid)
{
return validationResult.FirstError();
}
validationResult = Method2("Samsung");
if (!validationResult.IsValid)
{
return validationResult.FirstError();
}
validationResult = Method3(15.5);
if (!validationResult.IsValid)
{
return validationResult.FirstError();
}
答案 0 :(得分:3)
谓词可能是?
你可以做点什么 public ValidationResult Method1(string name)
{
return Validate(name, (param) => param.Length > 20, "Invalid name");
}
public ValidationResult Method1(double average)
{
return Validate(average, (param) => param < 14, "Invalid average");
}
private ValidationResult Validate<T>(T param, Func<T, bool> predicate, string message)
{
var validationResult = new validationResult();
if (predicate(param))
{
validationResult.Errors.Add(new ValidationFailure("", message));
}
return validationResult;
}
如果你有很多参数。这不是最好的方法,但是:
public ValidationResult Method1(int number, string family)
{
return Validate(number > 10 || family == "akbari", "Invalid Number");
}
public ValidationResult Method1(string name)
{
return Validate(name.Length > 20, "Invalid name");
}
public ValidationResult Method1(double average)
{
return Validate(average < 14, "Invalid average");
}
public ValidationResult Validate(bool predicate, string message)
{
var validationResult = new validationResult();
if (predicate)
{
validationResult.Errors.Add(new ValidationFailure("", message));
}
return validationResult;
}
答案 1 :(得分:3)
(另请查看以下备用解决方案!)
var valMethods = new List<Func<ValidationResult>>
{
()=>Method1(number,family),
()=>Method2(name),
// ...
};
foeach(var valMethod in valMethods)
{
var valResult = valMethod();
if (!valResult.IsValid)
{
return valResult.Errors.First();
}
}
然而,这会给代表带来一些性能损失,并且由于你需要参数,所以很难放在外面,例如:在一个返回代表的方法中。
作为替代方案,您可以创建一个值包作为参数(可能是具有适当接口的调用类),这对于所有方法都是相同的,并且每个方法都会选择它所需要的(反过来,它会使得验证方法不太清楚)。
另一种选择是返回bool值并将验证细节保存在单独的对象中,可能实现验证的扩展方法(也检查Myleo的谓词答案):
internal static class ValidationMethods
{
public static bool CheckIsValid1(this IList<ValidationResult> valResults, int number, string family)
{
var validationResult = new validationResult();
if(number > 10 || family="akbari")
{
validationResult.Errors.Add(new ValidationFailure("", "Invalid Number"));
}
valResults.Add(validationResult);
return validationResult.IsValid;
}
public static bool CheckIsValid2(this IList<ValidationResult> valResults, string name)
{
// next check ...
}
}
然后,在验证代码时:
var valResults = new List<ValidationResult>();
if (!valResults.CheckIsValid1(number, family)
|| !valResults.CheckIsValid2(name)
|| // more checks... will stop if one fails
)
{
return valResults.Last().Errors.First();
}
这样,您就不必与代表混淆了。当第一次失败时检查停止(||或条件检查在第一次成功时停止,这里是否定的IsValid)。您的valResults仍包含验证数据。
从您的代码中,简单地使用异常也是可行的。如果错误频繁发生,则可能需要进行此类无异常验证,异常会导致性能下降,但如果错误异常,则可以随意使用异常!
答案 2 :(得分:2)
我猜一个问题是方法签名,一些接受int,而另一些接受string..etc;如何创建一个新类型,比如InputParam:
B = mk.Banana(0.99)
然后,您可能拥有所需数量的方法,Method1最多可达20.当然,每个方法都只负责从InputParam实例中仅选取所需的字段。
现在,您的所有方法共享相同的签名,因此您可以拥有一组方法并对其进行循环。
答案 3 :(得分:1)
您可以使用 这样的
关键字 static void Main(string[] args)
{
Console.WriteLine(@"
Method1(1)-> return {0};
Method1('1')-> return {1};
Method1(0.1)->-> return {2};"
, Method1(1),
Method1("1"),
Method1(0.1));
Console.WriteLine(@"
AvgMethod()-> return {0};
AvgMethod(1)-> return {1};
AvgMethod('1')-> return {2};
AvgMethod(0.1)-> return {3};"
, AvgMethod()
, AvgMethod(1)
, AvgMethod("1")
, AvgMethod(0.1));
Console.ReadLine();
}
public static string Method1(int number)
{
return "int";
}
public static string Method1(string name)
{
return "string";
}
public static string Method1(double average)
{
return "double";
}
public static string AvgMethod(object _argument = null)
{
if (_argument is int)
return "int";
if (_argument is string)
return "string";
if (_argument is double)
return "double";
return "...";
}