重构两个非常相似的重载
Refactoring two very similar overloads
我有一个过载:
public DataTable ExecuteStoredProcedure(string storedProcedure)
{
var dataTable = new DataTable();
using (var odbcConnection = _connection)
{
using (var odbcCommand = odbcConnection.CreateCommand())
{
odbcCommand.CommandText = storedProcedure;
odbcCommand.CommandType = CommandType.StoredProcedure;
using (var adapter = new OdbcDataAdapter(odbcCommand))
{
adapter.Fill(dataTable);
}
}
}
return dataTable;
}
和另一个超载:
public DataTable ExecuteStoredProcedure(string storedProcedure, List<StoredProcedureParameters> storedProcedureParameters)
{
var dataTable = new DataTable();
using (var odbcConnection = _connection)
{
using (var odbcCommand = odbcConnection.CreateCommand())
{
odbcCommand.CommandText = storedProcedure;
foreach (var parameter in storedProcedureParameters)
{
odbcCommand.Parameters.Add("@" + parameter.ParameterName, parameter.ParameterType,
parameter.LengthOfParameter).Value = parameter.ParameterName;
}
odbcCommand.CommandType = CommandType.StoredProcedure;
using (var adapter = new OdbcDataAdapter(odbcCommand))
{
adapter.Fill(dataTable);
}
}
}
return dataTable;
}
他们的内容非常相似。事实上如此相似,唯一的区别是这里的这一行:
foreach (var parameter in storedProcedureParameters)
{
odbcCommand.Parameters.Add("@" + parameter.ParameterName, parameter.ParameterType,
parameter.LengthOfParameter).Value = parameter.ParameterName;
}
我花了几个小时试图重构这个人,因为他们是如此相似。我试过委托,但它使代码更难读。我无法组合这两个重载的功能,因为另一个重载逻辑出现在另一个重载的中间。有没有人知道如何将其重构为一种可读的方法?
如果你想运行 foreach 与否,你可以添加一个标志来标记。当然需要更改参数名称,这只是重构的一种可能变体:
public DataTable ExecuteStoredProcedure(string storedProcedure, List<StoredProcedureParameters> storedProcedureParameters, bool withForEach)
{
var dataTable = new DataTable();
using (var odbcConnection = _connection)
{
using (var odbcCommand = odbcConnection.CreateCommand())
{
odbcCommand.CommandText = storedProcedure;
if(withForEach)
foreach (var parameter in storedProcedureParameters)
{
odbcCommand.Parameters.Add("@" + parameter.ParameterName, parameter.ParameterType,
parameter.LengthOfParameter).Value = parameter.ParameterName;
}
odbcCommand.CommandType = CommandType.StoredProcedure;
using (var adapter = new OdbcDataAdapter(odbcCommand))
{
adapter.Fill(dataTable);
}
}
}
return dataTable;
}
您可以做几件事:
您始终可以只使用一种方法,但可以使用可选的方法 List<StoredProcedureParameters>
。
像这样:(为简洁起见,我已将其重命名为 spParams
)
public DataTable ExecuteStoredProcedure(string storedProcedure,
List<StoredProcedureParameters> spParams
= new List<StoredProcedureParameters>())
{
var dataTable = new DataTable();
using (var odbcConnection = _connection)
{
using (var odbcCommand = odbcConnection.CreateCommand())
{
odbcCommand.CommandText = storedProcedure;
foreach (var parameter in spParams)
{
odbcCommand.Parameters.Add("@" + parameter.ParameterName, parameter.ParameterType,
parameter.LengthOfParameter).Value = parameter.ParameterName;
}
odbcCommand.CommandType = CommandType.StoredProcedure;
using (var adapter = new OdbcDataAdapter(odbcCommand))
{
adapter.Fill(dataTable);
}
}
}
return dataTable;
}
这样调用同样的方法,选择是否传入List<StoredProcedureParameters>
。
使用默认值为 spParams= new List<StoredProcedureParameters>()
的参数意味着调用原始 1 参数签名的任何现有代码仍然有效,从而节省额外重构的时间。
另外,这意味着您现有的 foreach
块将只遍历一个空列表。
或
你可以像上面那样做,只是让 spParams
的值默认为 null
,然后做一个 null 检查,像这样:
public DataTable ExecuteStoredProcedure(string storedProcedure,
List<StoredProcedureParameters> spParams = null)
{
//...
if (spParams != null) // Check if the spParams is null
{
foreach(var param in spParams)
{
// Loop in here, if not null
}
}
//...
}
希望对您有所帮助:)
为什么你不能做这样的事情...
public DataTable ExecuteStoredProcedure(string storedProcedure)
{
return ExecuteStoredProcedure(storedProcedure, null);
}
public DataTable ExecuteStoredProcedure(string storedProcedure, List<StoredProcedureParameters> storedProcedureParameters)
{
var dataTable = new DataTable();
using (var odbcConnection = _connection)
{
using (var odbcCommand = odbcConnection.CreateCommand())
{
odbcCommand.CommandText = storedProcedure;
if(storedProcedureParameters != null)
{
foreach (var parameter in storedProcedureParameters)
{
odbcCommand.Parameters.Add("@" + parameter.ParameterName, parameter.ParameterType,
parameter.LengthOfParameter).Value = parameter.ParameterName;
}
}
odbcCommand.CommandType = CommandType.StoredProcedure;
using (var adapter = new OdbcDataAdapter(odbcCommand))
{
adapter.Fill(dataTable);
}
}
}
return dataTable;
}
两种方法-
您可以让第一个方法将空参数列表传递给第二个方法:
public DataTable ExecuteStoredProcedure(string storedProcedure)
{
return ExecuteStoredProcedure(storedProcedure, new List<StoredProcedureParameters>());
}
您可以从第一种方法传递 null 并在第二种方法中添加 null 检查,如下所示:
public DataTable ExecuteStoredProcedure(string storedProcedure)
{
return ExecuteStoredProcedure(storedProcedure, null);
}
...
if (storedProcedureParameters != null)
{
foreach (var parameter in storedProcedureParameters)
{
odbcCommand.Parameters.Add("@" + parameter.ParameterName, parameter.ParameterType, parameter.LengthOfParameter).Value = parameter.ParameterName;
}
}
我有一个过载:
public DataTable ExecuteStoredProcedure(string storedProcedure)
{
var dataTable = new DataTable();
using (var odbcConnection = _connection)
{
using (var odbcCommand = odbcConnection.CreateCommand())
{
odbcCommand.CommandText = storedProcedure;
odbcCommand.CommandType = CommandType.StoredProcedure;
using (var adapter = new OdbcDataAdapter(odbcCommand))
{
adapter.Fill(dataTable);
}
}
}
return dataTable;
}
和另一个超载:
public DataTable ExecuteStoredProcedure(string storedProcedure, List<StoredProcedureParameters> storedProcedureParameters)
{
var dataTable = new DataTable();
using (var odbcConnection = _connection)
{
using (var odbcCommand = odbcConnection.CreateCommand())
{
odbcCommand.CommandText = storedProcedure;
foreach (var parameter in storedProcedureParameters)
{
odbcCommand.Parameters.Add("@" + parameter.ParameterName, parameter.ParameterType,
parameter.LengthOfParameter).Value = parameter.ParameterName;
}
odbcCommand.CommandType = CommandType.StoredProcedure;
using (var adapter = new OdbcDataAdapter(odbcCommand))
{
adapter.Fill(dataTable);
}
}
}
return dataTable;
}
他们的内容非常相似。事实上如此相似,唯一的区别是这里的这一行:
foreach (var parameter in storedProcedureParameters)
{
odbcCommand.Parameters.Add("@" + parameter.ParameterName, parameter.ParameterType,
parameter.LengthOfParameter).Value = parameter.ParameterName;
}
我花了几个小时试图重构这个人,因为他们是如此相似。我试过委托,但它使代码更难读。我无法组合这两个重载的功能,因为另一个重载逻辑出现在另一个重载的中间。有没有人知道如何将其重构为一种可读的方法?
如果你想运行 foreach 与否,你可以添加一个标志来标记。当然需要更改参数名称,这只是重构的一种可能变体:
public DataTable ExecuteStoredProcedure(string storedProcedure, List<StoredProcedureParameters> storedProcedureParameters, bool withForEach)
{
var dataTable = new DataTable();
using (var odbcConnection = _connection)
{
using (var odbcCommand = odbcConnection.CreateCommand())
{
odbcCommand.CommandText = storedProcedure;
if(withForEach)
foreach (var parameter in storedProcedureParameters)
{
odbcCommand.Parameters.Add("@" + parameter.ParameterName, parameter.ParameterType,
parameter.LengthOfParameter).Value = parameter.ParameterName;
}
odbcCommand.CommandType = CommandType.StoredProcedure;
using (var adapter = new OdbcDataAdapter(odbcCommand))
{
adapter.Fill(dataTable);
}
}
}
return dataTable;
}
您可以做几件事:
您始终可以只使用一种方法,但可以使用可选的方法 List<StoredProcedureParameters>
。
像这样:(为简洁起见,我已将其重命名为 spParams
)
public DataTable ExecuteStoredProcedure(string storedProcedure,
List<StoredProcedureParameters> spParams
= new List<StoredProcedureParameters>())
{
var dataTable = new DataTable();
using (var odbcConnection = _connection)
{
using (var odbcCommand = odbcConnection.CreateCommand())
{
odbcCommand.CommandText = storedProcedure;
foreach (var parameter in spParams)
{
odbcCommand.Parameters.Add("@" + parameter.ParameterName, parameter.ParameterType,
parameter.LengthOfParameter).Value = parameter.ParameterName;
}
odbcCommand.CommandType = CommandType.StoredProcedure;
using (var adapter = new OdbcDataAdapter(odbcCommand))
{
adapter.Fill(dataTable);
}
}
}
return dataTable;
}
这样调用同样的方法,选择是否传入List<StoredProcedureParameters>
使用默认值为 spParams= new List<StoredProcedureParameters>()
的参数意味着调用原始 1 参数签名的任何现有代码仍然有效,从而节省额外重构的时间。
另外,这意味着您现有的 foreach
块将只遍历一个空列表。
或
你可以像上面那样做,只是让 spParams
的值默认为 null
,然后做一个 null 检查,像这样:
public DataTable ExecuteStoredProcedure(string storedProcedure,
List<StoredProcedureParameters> spParams = null)
{
//...
if (spParams != null) // Check if the spParams is null
{
foreach(var param in spParams)
{
// Loop in here, if not null
}
}
//...
}
希望对您有所帮助:)
为什么你不能做这样的事情...
public DataTable ExecuteStoredProcedure(string storedProcedure)
{
return ExecuteStoredProcedure(storedProcedure, null);
}
public DataTable ExecuteStoredProcedure(string storedProcedure, List<StoredProcedureParameters> storedProcedureParameters)
{
var dataTable = new DataTable();
using (var odbcConnection = _connection)
{
using (var odbcCommand = odbcConnection.CreateCommand())
{
odbcCommand.CommandText = storedProcedure;
if(storedProcedureParameters != null)
{
foreach (var parameter in storedProcedureParameters)
{
odbcCommand.Parameters.Add("@" + parameter.ParameterName, parameter.ParameterType,
parameter.LengthOfParameter).Value = parameter.ParameterName;
}
}
odbcCommand.CommandType = CommandType.StoredProcedure;
using (var adapter = new OdbcDataAdapter(odbcCommand))
{
adapter.Fill(dataTable);
}
}
}
return dataTable;
}
两种方法-
您可以让第一个方法将空参数列表传递给第二个方法:
public DataTable ExecuteStoredProcedure(string storedProcedure) { return ExecuteStoredProcedure(storedProcedure, new List<StoredProcedureParameters>()); }
您可以从第一种方法传递 null 并在第二种方法中添加 null 检查,如下所示:
public DataTable ExecuteStoredProcedure(string storedProcedure) { return ExecuteStoredProcedure(storedProcedure, null); }
...
if (storedProcedureParameters != null) { foreach (var parameter in storedProcedureParameters) { odbcCommand.Parameters.Add("@" + parameter.ParameterName, parameter.ParameterType, parameter.LengthOfParameter).Value = parameter.ParameterName; } }