【发布时间】:2012-10-25 21:27:06
【问题描述】:
我的情况是这样的。我需要在多种不同类型的对象上运行一些验证和按摩类型代码,但是为了清洁(和代码重用),我想让这个验证的所有调用看起来基本相同,无论对象如何。我正在尝试通过重载来解决这个问题,在我得到通用集合对象之前效果很好。
下面的例子应该澄清我在这里所说的:
private string DoStuff(string tmp) { ... }
private ObjectA DoStuff(ObjectA tmp) { ... }
private ObjectB DoStuff(ObjectB tmp) { ... }
...
private Collection<ObjectA> DoStuff(Collection<ObjectA> tmp) {
foreach (ObjectA obj in tmp) if (DoStuff(obj) == null) tmp.Remove(obj);
if (tmp.Count == 0) return null;
return tmp;
}
private Collection<Object> DoStuff(Collection<ObjectB> tmp) {
foreach (ObjectB obj in tmp) if (DoStuff(obj) == null) tmp.Remove(obj);
if (tmp.Count == 0) return null;
return tmp;
}
...
这似乎是一种真正的浪费,因为我必须为每个不同的Collection<T> 类型复制完全相同的代码。我想创建一个处理任何Collection<T> 的DoStuff 实例,而不是为每个实例单独创建一个。
我曾尝试使用ICollection,但这有两个问题:第一,ICollection 没有暴露.Remove 方法,并且我无法编写foreach 循环,因为我不知道类型列表中的对象。使用更通用的东西,比如object,是行不通的,因为我没有接受object 的方法DoStuff - 我需要它为实际对象调用适当的方法。编写一个 DoStuff 方法,该方法采用 object 并执行某种庞大的 if 语句列表来选择正确的方法并适当地进行转换,这违背了摆脱冗余代码的整个想法——我不妨复制并粘贴所有Collection<T> 方法。
我尝试过使用通用的DoStuff<T> 方法,但这在foreach 循环中存在同样的问题。因为我在设计时不知道对象类型,所以编译器不会让我调用DoStuff(obj)。
从技术上讲,编译器应该能够在编译时判断需要进行哪个调用,因为这些都是私有方法,并且在调用中传递的对象的具体类型在方法所在的点都是已知的被调用。这些知识似乎并没有出现在此方法调用的后续方法中。
我真的不想在这里使用反射,因为这会使代码比复制和粘贴所有Collection<T> 方法更加复杂,并且会降低性能。有什么想法吗?
---编辑 1--- 我意识到我的通用方法引用没有正确显示,因为我没有使用尖括号的 html 代码。现在应该解决这个问题。
---编辑 2---
根据下面的回复,我将Collection<T> 方法更改为如下所示:
private Collection<T> DoStuff<T>(Collection<T> tmp) {
for (int i = tmp.Count - 1; i >= 0; i--) if (DoStuff(tmp[i]) == null) tmp.RemoveAt(i);
if (tmp.Count == 0) return null;
return tmp;
}
但是,这仍然不起作用,因为当我调用 DoStuff(tmp[i]) 时,编译器无法确定要调用哪个重载方法。
【问题讨论】:
标签: c# generics collections overloading generic-collections