C# 最佳实践-具有模拟意义的两个功能
我想知道在这种情况下什么是最佳做法。 就拿这两个功能来说吧 选项1-TableController.csC# 最佳实践-具有模拟意义的两个功能,c#,model-view-controller,design-patterns,C#,Model View Controller,Design Patterns,我想知道在这种情况下什么是最佳做法。 就拿这两个功能来说吧 选项1-TableController.cs void deleteRow(Row myRow) { // do some control on myRow if (!(myRow.hasThatValue()) && (myRow.Title.StartsWith("xxx")) return; Rows.Remove(myRow); Events.OnRemoveRo
void deleteRow(Row myRow) {
// do some control on myRow
if (!(myRow.hasThatValue()) && (myRow.Title.StartsWith("xxx"))
return;
Rows.Remove(myRow);
Events.OnRemoveRow(myRow);
}
void deleteRows(List<Row> myRows) {
foreach (var r in myRows) {
deleteRow(r); // That call each time OnRemoveRow()
}
}
void deleteRow(Row myRow) {
// do some control on myRow
if (!(myRow.hasThatValue()) && (myRow.Title.StartsWith("xxx"))
return;
Rows.Remove(myRow);
Events.OnRemoveRow(myRow);
}
void deleteRows(List<Row> myRows) {
foreach (var r in myRows) {
// do some control on myRow
if (!(r.hasThatValue()) && (r.Title.StartsWith("xxx"))
continue;
Rows.Remove(myRow);
}
Events.OnReloadTable(); // That call only one time OnReloadTable()
}
选项2-TableController.cs
void deleteRow(Row myRow) {
// do some control on myRow
if (!(myRow.hasThatValue()) && (myRow.Title.StartsWith("xxx"))
return;
Rows.Remove(myRow);
Events.OnRemoveRow(myRow);
}
void deleteRows(List<Row> myRows) {
foreach (var r in myRows) {
deleteRow(r); // That call each time OnRemoveRow()
}
}
void deleteRow(Row myRow) {
// do some control on myRow
if (!(myRow.hasThatValue()) && (myRow.Title.StartsWith("xxx"))
return;
Rows.Remove(myRow);
Events.OnRemoveRow(myRow);
}
void deleteRows(List<Row> myRows) {
foreach (var r in myRows) {
// do some control on myRow
if (!(r.hasThatValue()) && (r.Title.StartsWith("xxx"))
continue;
Rows.Remove(myRow);
}
Events.OnReloadTable(); // That call only one time OnReloadTable()
}
你能看出区别吗?假设您有1000行要删除,在事件OnRemoveRow中删除ListView中的一行,而在事件OnReloadTable中清除并重新加载ListView中的所有行
使用选项1,您将引发1000倍于在GUI中执行大量工作的事件,而使用选项2,您只调用一次重新加载所有行的事件
使用基准测试显然表明选项2的性能要好得多
因此,问题是:
有一种替代方法或更好的方法可以像选项2中一样重复相同的代码两次,但该解决方案的性能良好吗
编辑:
@Ulf:在示例中,使用continue修复了循环中的返回
正如Himbrombere建议的那样,我试图更好地解释这个问题:
我有一些用于删除一行的冗余代码,我正在尝试尽可能多的简化
从性能的角度来看,为每行触发一个事件是一种浪费。
我正在寻找一种在不影响性能的情况下编写更少代码的方法。
从答案中,我看到了两种解决这个问题的有效方法
就个人而言,第一个解决方案归功于:Yair Halberstadt
有一个内部方法可以解决代码冗余问题。
第二种解决方案是Mureinik的答案,将删除行的逻辑移动到删除行列表,并始终使用行列表,但每次创建单个元素的新列表时似乎都有点过多。如您所述,选项2的性能会更好,但它会在两种方法之间重复大量代码,并将导致难以维护的代码库 我选择第三个选项,其中deleteRows包含选项2的性能更好的逻辑,deleteRow重用它:
void deleteRow(Row myRow) {
deleteRows(new List<Row>(){myRow});
}
void deleteRows(List<Row> myRows) {
foreach (var r in myRows) {
// do some control on myRow
if (!(myRow.hasThatValue()) && (myRow.Title.StartsWith("xxx"))
return;
Rows.Remove(myRow);
}
Events.OnReloadTable();
}
添加第三个包含共享逻辑的方法deleteRowInternal
public void deleteRow(Row myRow) {
deleteRowInternal(myRow);
Events.OnRemoveRow(myRow);
}
private void deleteRowInternal(Row myRow) {
// do some control on myRow
if (!(myRow.hasThatValue()) &&
(myRow.Title.StartsWith("xxx"))
return;
Rows.Remove(myRow);
}
public void deleteRows(List<Row> myRows) {
foreach (var r in myRows) {
deleteRowInternal(r);
}
Events.OnReloadTable();
}
您的第二个选项与第一个选项不一致;如果第一行是正确的,则您希望删除所有具有该值且不以xxx开头的行:
为了避免此类错误,我建议使用Linq进行查询
我想说第四点:不要回答这个问题,因为OP想要什么完全不清楚。最佳实践往往是基于意见的,特别是在我们对OPs环境一无所知的情况下。这是一个很好的解决方案,但我认为每次删除一行时创建一个新列表会导致一些开销。这完全取决于您的环境和上下文。然而,如果你已经做了基准测试,为什么不信任它们呢?当你的代码做了它应该做的事情时,你到底在问什么?请注意,你应该继续而不是在选项2中返回,以便表现得像选项1一样。@HimBromBeere:我想减少冗余的Codebase如果我理解正确,你会想要一个Events.OnReloadTable;在deleteRows方法中…有一个内部方法的很好的解决方案!