c# 使用空检查重构 switch 语句
c# Refactor switch statement with null check
我只是在处理几个 switch 语句时遇到了一些麻烦,我觉得有更好的方法来实现最终目标。
所以基本上我将 viewmodel 传递给一个方法。该方法首先从数据库中检索视图模型相关的对象,然后 switch 语句对特定的 属性 进行空检查。基于该结果,另一个 switch 语句对视图模型进行另一个空检查。在每个点,值都从数据库分配给对象,然后在最后发生数据库更新。
这是代码
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 检查。
感谢任何帮助!
我不完全确定你被困在哪里 - 但用 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);
}
我真的会在 bool 条件下使用 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);
}
如果你只取出两个布尔值,整个代码可以简化:
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;
}
您可以通过将嵌套的 switch 条件组合到使用多个条件的 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;
}
我只是在处理几个 switch 语句时遇到了一些麻烦,我觉得有更好的方法来实现最终目标。
所以基本上我将 viewmodel 传递给一个方法。该方法首先从数据库中检索视图模型相关的对象,然后 switch 语句对特定的 属性 进行空检查。基于该结果,另一个 switch 语句对视图模型进行另一个空检查。在每个点,值都从数据库分配给对象,然后在最后发生数据库更新。
这是代码
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 检查。
感谢任何帮助!
我不完全确定你被困在哪里 - 但用 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);
}
我真的会在 bool 条件下使用 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);
}
如果你只取出两个布尔值,整个代码可以简化:
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;
}
您可以通过将嵌套的 switch 条件组合到使用多个条件的 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;
}