消滅代碼中的 if :請(qǐng)求參數(shù)校驗(yàn)的優(yōu)雅之道
在軟件開(kāi)發(fā)中,參數(shù)校驗(yàn)是一個(gè)非常重要的環(huán)節(jié)。它不僅能確保數(shù)據(jù)的完整性和準(zhǔn)確性,還能在一定程度上防止?jié)撛诘陌踩L(fēng)險(xiǎn)。然而,傳統(tǒng)的參數(shù)校驗(yàn)方法往往充斥著大量的if語(yǔ)句,這不僅讓代碼變得冗長(zhǎng)且難以維護(hù),還降低了代碼的可讀性和優(yōu)雅性。
那么,如何干掉這些煩人的if語(yǔ)句,讓參數(shù)校驗(yàn)變得更加優(yōu)雅呢?下面,我們將通過(guò)C#的例子來(lái)探討這個(gè)問(wèn)題。

使用特性(Attributes)進(jìn)行校驗(yàn)
C# 提供了豐富的特性(Attributes)機(jī)制,我們可以利用這一機(jī)制來(lái)進(jìn)行參數(shù)校驗(yàn)。通過(guò)定義自定義的特性,并將這些特性應(yīng)用于方法的參數(shù)上,我們可以在運(yùn)行時(shí)自動(dòng)進(jìn)行參數(shù)校驗(yàn),從而避免了大量的if語(yǔ)句。
下面是一個(gè)簡(jiǎn)單的例子,展示如何使用自定義特性進(jìn)行參數(shù)校驗(yàn):
using System;
using System.Reflection;
// 定義一個(gè)自定義的校驗(yàn)特性
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)]
public class NotNullAttribute : Attribute
{
    // 可以在這里添加一些自定義的邏輯
}
public class Validator
{
    public static void ValidateParameters(MethodInfo method, object[] parameters)
    {
        ParameterInfo[] paramInfos = method.GetParameters();
        for (int i = 0; i < paramInfos.Length; i++)
        {
            object param = parameters[i];
            NotNullAttribute attr = paramInfos[i].GetCustomAttribute<NotNullAttribute>();
            if (attr != null && param == null)
            {
                throw new ArgumentNullException(paramInfos[i].Name);
            }
            // 可以根據(jù)需要添加更多的校驗(yàn)邏輯
        }
    }
}
public class ExampleService
{
    public void ExampleMethod([NotNull] string param1, int param2)
    {
        // 方法體
    }
}
public class Program
{
    public static void Main(string[] args)
    {
        ExampleService service = new ExampleService();
        MethodInfo method = typeof(ExampleService).GetMethod("ExampleMethod");
        object[] parameters = new object[] { null, 123 }; // 這里故意傳入一個(gè)null值以觸發(fā)校驗(yàn)失敗
        Validator.ValidateParameters(method, parameters); // 這行會(huì)拋出ArgumentNullException異常,因?yàn)閜aram1為null且被標(biāo)記為[NotNull]
        // 如果校驗(yàn)通過(guò),則繼續(xù)執(zhí)行方法體
        // method.Invoke(service, parameters); // 實(shí)際使用時(shí),在校驗(yàn)通過(guò)后再調(diào)用方法
    }
}在這個(gè)例子中,我們定義了一個(gè)NotNullAttribute特性,并將其應(yīng)用于ExampleMethod方法的param1參數(shù)上。然后,我們創(chuàng)建了一個(gè)Validator類(lèi),該類(lèi)具有一個(gè)靜態(tài)方法ValidateParameters,該方法接受一個(gè)MethodInfo對(duì)象和一個(gè)參數(shù)數(shù)組,并對(duì)參數(shù)進(jìn)行校驗(yàn)。如果某個(gè)參數(shù)被標(biāo)記為NotNull但值為null,則該方法會(huì)拋出一個(gè)ArgumentNullException異常。
使用FluentValidation庫(kù)
除了使用自定義特性外,我們還可以利用現(xiàn)有的校驗(yàn)庫(kù)來(lái)簡(jiǎn)化參數(shù)校驗(yàn)。FluentValidation是一個(gè)流行的.NET校驗(yàn)庫(kù),它提供了豐富的校驗(yàn)規(guī)則和友好的API。
下面是一個(gè)使用FluentValidation進(jìn)行參數(shù)校驗(yàn)的例子:
首先,安裝FluentValidation NuGet包:
Install-Package FluentValidation然后,創(chuàng)建一個(gè)校驗(yàn)器類(lèi):
using FluentValidation;
public class ExampleValidator : AbstractValidator<ExampleRequest>
{
    public ExampleValidator()
    {
        RuleFor(x => x.Param1).NotNull().WithMessage("Param1 cannot be null");
        RuleFor(x => x.Param2).GreaterThan(0).WithMessage("Param2 must be greater than 0");
        // 可以根據(jù)需要添加更多的校驗(yàn)規(guī)則
    }
}
public class ExampleRequest
{
    public string Param1 { get; set; }
    public int Param2 { get; set; }
}在業(yè)務(wù)邏輯中使用校驗(yàn)器:
public class ExampleService
{
    private readonly ExampleValidator _validator;
    
    public ExampleService()
    {
        _validator = new ExampleValidator();
    }
    
    public void ExampleMethod(ExampleRequest request)
    {
        ValidationResult result = _validator.Validate(request);
        if (!result.IsValid)
        {
            throw new ValidationException(result.Errors); // 這里可以自定義異常處理邏輯
        }
        // 如果校驗(yàn)通過(guò),則繼續(xù)執(zhí)行方法體
    }
}在這個(gè)例子中,我們創(chuàng)建了一個(gè)ExampleValidator類(lèi),該類(lèi)繼承了FluentValidation的AbstractValidator類(lèi),并定義了校驗(yàn)規(guī)則。然后,在ExampleService類(lèi)的ExampleMethod方法中,我們使用ExampleValidator對(duì)請(qǐng)求參數(shù)進(jìn)行校驗(yàn)。如果校驗(yàn)失敗,我們拋出一個(gè)自定義的異常。這種方法使代碼更加清晰和易于維護(hù),同時(shí)避免了大量的if語(yǔ)句。















 
 
 











 
 
 
 