我正在重构一些代码,我编写了一个修改 Dictionary 并返回它的方法。这比使用 out 参数更好吗?在这种情况下,我真的不想创建一个扩展方法,因为它会将方法添加到 Dictionary 类中,这对于它的用途来说是过度的。请不要指出我不应该使用动态sql,这是目前必须推迟的重构中的另一个阶段。
private static Dictionary<int, string>
FindMatches(Dictionary<int, string> records,
string queryFormat,
string region,
string type,
string label)
{
var query = string.Format(queryFormat, SqlSvrName, SqlDbName, SqlSchemaName,
region, type, label);
using (var dr = DataRepository.Provider.ExecuteReader(CommandType.Text, query))
{
if (dr != null && !dr.IsClosed)
{
while (dr.Read())
{
var assetID = (int)dr.GetDouble(0);
if (!records.ContainsKey(assetID))
records[assetID] = dr.GetString(1);
}
}
}
return records;
}
编辑:我对上面使用 out 一词感到有些仓促。我试图在我的代码中明确表示该方法修改了字典。这里的out参数只有在方法创建了一个新字典并通过该参数返回时才有意义。为此更多的上下文是使用不同的查询字符串多次调用该方法,并且字典可能已经包含匹配。
Edit2:为了跟进,我删除了记录参数,而是从 FindMatches 返回 KeyValuePair 的列表。我最终得到了List<KeyValuePair<int, string>>
,我通过以下方式转换为字典:
records
.GroupBy(rec => rec.Key)
.ToDictionary(grp => grp.Key, grp => grp.First().Value);
答案 0 :(得分:9)
为什么你的方法应该修改现有的字典?它似乎没有使用现有的键/值,因此使这个方法只返回一个新的Dictionary<string, int>
:
private static Dictionary<int, string>
FindMatches(string queryFormat,
string region,
string type,
string label)
{
var records = new Dictionary<int, string>();
var query = string.Format(queryFormat, SqlSvrName, SqlDbName,
SqlSchemaName, region, type, label);
using (var dr = DataRepository.Provider.ExecuteReader(CommandType.Text,
query))
{
if (dr != null && !dr.IsClosed)
{
while (dr.Read())
{
var assetID = (int)dr.GetDouble(0);
// If each assetID in the database will be distinct, you
// don't need the "if" here, because you know the dictionary
// is empty to start with
if (!records.ContainsKey(assetID))
{
records[assetID] = dr.GetString(1);
}
}
}
}
return records;
}
然后你可以还编写一个单独的方法来以特定方式合并两个字典 - 或者返回一个新字典,这是合并两个现有字典的结果。分开这两个问题。
答案 1 :(得分:4)
由于你实际上并没有在方法中使用Dictionary(除了填充它),我会从输入参数中删除它而只是返回它。
如果由于某种原因你必须将字典作为参数传递,我会有一个void返回并重命名该方法,以确保它对输入参数有明显的副作用 - 例如
void PopulateRecordsWithMatches(Dictionary<int, string> records...)
答案 2 :(得分:2)
我相信C#中所有复杂对象的引用都是通过引用传递的。因此,如果您通过方法内部的引用修改字典,则无需返回它或指定out / ref关键字。它将在方法范围之外进行更改。
答案 3 :(得分:0)
out
参数意味着您传入一个空字典。这没有意义。您可能需要ref
参数。
但正如Kon所说,你可以修改方法内对象的内容。
答案 4 :(得分:-2)
由于您正在修改字典,我认为最好通过将其作为ref参数来明确:
private static void
FindMatches(ref Dictionary<int, string> records,
string queryFormat,
string region,
string type,
string label)
{
var query = string.Format(queryFormat, SqlSvrName, SqlDbName, SqlSchemaName,
region, type, label);
using (var dr = DataRepository.Provider.ExecuteReader(CommandType.Text, query))
{
if (dr != null && !dr.IsClosed)
{
while (dr.Read())
{
var assetID = (int)dr.GetDouble(0);
if (!records.ContainsKey(assetID))
records[assetID] = dr.GetString(1);
}
}
}
}
返回它或将其用作out参数都意味着你正在创建一个新的字典,但事实并非如此。另一方面,明确地将其作为ref参数,清楚地表明您打算将字典修改为副作用。