c#用null检查重构switch语句

本文关键字:switch 语句 重构 检查 null | 更新日期: 2024-09-19 19:53:20

我只是在一些switch语句上遇到了一些麻烦,我觉得有更好的方法来实现最终目标。

所以本质上我是在把视图模型传递到一个方法中。该方法首先从数据库中检索视图模型相关的对象,然后switch语句对特定属性进行null检查。基于该结果,另一个switch语句对视图模型执行另一个null检查。在每一点上,都会从数据库中为对象指定值,然后在最后进行数据库更新。

这是代码

        public async Task UpdateContractWithRepository(ViewModel viewModel)
    {
        // Get the contract from db
        Contract contract = GetContract(viewModel.Id);
        switch (viewModel.RepositoryId == null)
        {
            case true:
                switch (contract.RepositoryId == null)
                {
                    case true:
                        // nothing to do
                        // no change
                        break;
                    case false:
                        // Unassign Repository
                        UpdateRepositoryAssignment(contract.RepositoryId, false);
                        // Update properties
                        contract.RepositoryId = null;
                        contract.ConsumedUnits = null;
                        break;
                }
                break;
            case false:
                switch (contract.RepositoryId == null)
                {
                    case true:
                        // assign repository
                        UpdateRepositoryAssignment(viewModel.RepositoryId, true);
                        // Get repository
                        Repository repository = GetRepository(viewModel.RepositoryId);
                        // Update properties
                        contract.RepositoryId = repository.Id;
                        contract.ConsumedUnits = repository.Units;
                        break;
                    case false:
                        // assign repository
                        UpdateRepositoryAssignment(viewModel.RepositoryId, true);
                        // Get repository
                        Repository repository = GetRepository(viewModel.RepositoryId);
                        // Update properties
                        contract.RepositoryId = repository.Id;
                        contract.ConsumedUnits = repository.Units;
                        break;
                }
                break;
        }
        UpdateContract(contract);
    }

我想我可能可以取消switch语句,而使用if语句,根据我的判断,仍然会有一些嵌套。只是想知道是否有人有任何建议。

我在这里看了重构switch语句,但它们似乎并没有真正涵盖null检查。

感谢您的帮助!

c#用null检查重构switch语句

如果去掉两个布尔,整个代码就可以简化:

bool IsVMRepoNull = viewModel.RepositoryId == null;
bool IsContractRepoNull = contract.RepositoryId == null;
if(IsVMRepoNull && !IsContractRepoNull )
{
  UpdateRepositoryAssignment(contract.RepositoryId, false);
 // Update properties
  contract.RepositoryId = null;
  contract.ConsumedUnits = null;
}
else if(!IsVMRepoNull)
{
  UpdateRepositoryAssignment(viewModel.RepositoryId, true);
  // Get repository
  Repository repository = GetRepository(viewModel.RepositoryId);
  // Update properties
  contract.RepositoryId = repository.Id;
  contract.ConsumedUnits = repository.Units;
}

我不完全确定您被困在哪里了,但用if/else替换开关几乎就像用if替换switch一样简单。这是转换后的代码:

public async Task UpdateContractWithRepository(ViewModel viewModel)
{
    // Get the contract from db
    Contract contract = GetContract(viewModel.Id);
    if (viewModel.RepositoryId == null)
    {
        if (contract.RepositoryId == null)
        {
            // nothing to do
            // no change
        } else {
            // Unassign Repository
            UpdateRepositoryAssignment(contract.RepositoryId, false);
            // Update properties
            contract.RepositoryId = null;
            contract.ConsumedUnits = null;
        }
    } else {
        if (contract.RepositoryId == null)
        {
            // assign repository
            UpdateRepositoryAssignment(viewModel.RepositoryId, true);
            // Get repository
            Repository repository = GetRepository(viewModel.RepositoryId);
            // Update properties
            contract.RepositoryId = repository.Id;
            contract.ConsumedUnits = repository.Units;
        } else {
            // assign repository
            UpdateRepositoryAssignment(viewModel.RepositoryId, true);
            // Get repository
            Repository repository = GetRepository(viewModel.RepositoryId);
            // Update properties
            contract.RepositoryId = repository.Id;
            contract.ConsumedUnits = repository.Units;
        }
    }
    UpdateContract(contract);
}

我认为没有必要这么复杂。试试这个,我认为它做同样的工作:

public async Task UpdateContractWithRepository(ViewModel viewModel){
        Contract contract = GetContract(viewModel.Id);
        if (viewModel.RepositoryId == null)
        {
            if(contract.RepositoryId != null){
                UpdateRepositoryAssignment(contract.RepositoryId, false);
                contract.RepositoryId = null;
                contract.ConsumedUnits = null;
            }
        }
        else
        {
            if (contract.RepositoryId == null)
            {
                UpdateRepositoryAssignment(viewModel.RepositoryId, true);
                Repository repository = GetRepository(viewModel.RepositoryId);
                contract.RepositoryId = repository.Id;
                contract.ConsumedUnits = repository.Units;
            }
            else
            {
                UpdateRepositoryAssignment(viewModel.RepositoryId, true);
                Repository repository = GetRepository(viewModel.RepositoryId);
                contract.RepositoryId = repository.Id;
                contract.ConsumedUnits = repository.Units;
            }
        }
        UpdateContract(contract);
    }

我真的会在布尔条件下使用if....else if。您可以使用有意义的变量名称使其更具可读性:

public async Task UpdateContractWithRepository(ViewModel viewModel)
{
    // Get the contract from db
    Contract contract = GetContract(viewModel.Id);
    bool modelRepositoryKnown = viewModel.RepositoryId != null;
    bool contractRepositoryKnown = contract.RepositoryId != null;
    if (modelRepositoryKnown)
    {
        if (contractRepositoryKnown)
        {
            // assign repository
            UpdateRepositoryAssignment(viewModel.RepositoryId, true);
            // Get repository
            Repository repository = GetRepository(viewModel.RepositoryId);
            // Update properties
            contract.RepositoryId = repository.Id;
            contract.ConsumedUnits = repository.Units;
        }
        else
        {
            // assign repository
            UpdateRepositoryAssignment(viewModel.RepositoryId, true);
            // Get repository
            Repository repository = GetRepository(viewModel.RepositoryId);
            // Update properties
            contract.RepositoryId = repository.Id;
            contract.ConsumedUnits = repository.Units;
        }
    }
    else if(contractRepositoryKnown)  // Model-Repository unknown but Contract-Repository Known
    {
        // Unassign Repository
        UpdateRepositoryAssignment(contract.RepositoryId, false);
        // Update properties
        contract.RepositoryId = null;
        contract.ConsumedUnits = null;
        break;
    }
    UpdateContract(contract);
}

您可以通过将嵌套的开关条件组合到使用多个条件的if-else语句中来实现这一点。

if(viewModel.RepositoryId == null && !contract.RepositoryId)
{
    // Unassign Repository
    UpdateRepositoryAssignment(contract.RepositoryId, false);
    // Update properties
    contract.RepositoryId = null;
    contract.ConsumedUnits = null;
}
else if(!viewModel.RepositryId && contract.RepositoryId == null)
{
    // assign repository
    UpdateRepositoryAssignment(viewModel.RepositoryId, true);
    // Get repository
    Repository repository = GetRepository(viewModel.RepositoryId);
    // Update properties
    contract.RepositoryId = repository.Id;
    contract.ConsumedUnits = repository.Units;
} 
else if(!viewModel.RepositryId && !contract.RepositoryId == null)
{
    // assign repository
    UpdateRepositoryAssignment(viewModel.RepositoryId, true);
    // Get repository
    Repository repository = GetRepository(viewModel.RepositoryId);
    // Update properties
    contract.RepositoryId = repository.Id;
    contract.ConsumedUnits = repository.Units;
}