我正在尝试为自定义类型进行扩展。这是我的代码。我不知道我的源代码在此代码中是如何变为零的。即使在调试部分hashset temp中也给了我10个logevents的列表。但在决赛中,消息来源变为零。
public static void UnionSpecialWith(this HashSet<LogEvent> source, List<LogEvent> given,IEqualityComparer<LogEvent> comparer)
{
List<LogEvent> original = new List<LogEvent>(source);
List<LogEvent> second = given.Condense(comparer);
source = new HashSet<LogEvent>(original.Condense(comparer),comparer);
foreach (LogEvent logEvent in second)
{
if (original.Contains(logEvent, comparer))
{
int index = original.FindIndex(x => comparer.Equals(x, logEvent));
original[index].filesAndLineNos.MergeFilesAndLineNos(logEvent.filesAndLineNos);
}
else
original.Add(logEvent);
}
#if DEBUG
String content = String.Join(Environment.NewLine, original.Select(x => x.GetContentAsEventsOnly()));
HashSet<LogEvent> temp = new HashSet<LogEvent>(original, comparer);
#endif
source = new HashSet<LogEvent>(original, comparer);
}
有人能指出我的错误吗?
修改 这是我的自定义类型。每当我发现重复时,我想将它的“filesAndLineNos”与原始的一起合并。这是我试图用上面的代码实现的。
public class LogEvent
{
public String mainEventOriginal;
public String subEventOriginal;
public String mainEvent;
public String subEvent;
public int level;
public Dictionary<String,HashSet<int>> filesAndLineNos;
}
用法类似于
HashSet<LogEvent> required = new HashSet<LogEvent>(initialUniqueSet);
required.UnionSpecialWith(givenListOfLogEvents);
答案 0 :(得分:0)
这只是默认情况下.NET中的值传递的参数问题。您正在更改source
的值以引用其他HashSet
,并且根本不会更改调用方的变量。假设Condense
没有修改列表(我不知道那个方法),你的方法没有意义:
public void TrimString(string text)
{
// This changes the value of the *parameter*, but doesn't affect the original
// *object* (strings are immutable). The caller won't see any effect!
text = text.Trim();
}
如果您通过以下方式致电上述内容:
string foo = " hello ";
TrimString(foo);
...然后foo
仍将引用内容为“hello”的字符串。显然你的方法比较复杂,但问题的原因是一样的。
要么你的扩展方法需要修改通过HashSet
参数传入的原始source
的内容,或它应该返回新集。返回新集合更像是习惯性的LINQ,但是HashSet.UnionWith
会修改原始集合 - 它取决于您希望接近哪个模型。
public static void UnionSpecialWith(this HashSet<LogEvent> source,
List<LogEvent> given,
IEqualityComparer<LogEvent> comparer)
{
List<LogEvent> original = new List<LogEvent>(source);
List<LogEvent> second = given.Condense(comparer);
foreach (LogEvent logEvent in second)
{
if (original.Contains(logEvent, comparer))
{
int index = original.FindIndex(x => comparer.Equals(x, logEvent));
original[index].filesAndLineNos
.MergeFilesAndLineNos(logEvent.filesAndLineNos);
}
else
{
original.Add(logEvent);
}
}
source.Clear();
foreach (var item in original)
{
source.Add(item);
}
}
但是,请注意:
Dictionary
会更合适。