我的情况是这样的。我需要在多种不同类型的对象上运行一些验证和按摩类型代码,但是为了清洁(和代码重用),我想让这个验证的所有调用看起来基本相同,无论对象如何。我试图通过重载来解决这个问题,在我得到 Generic Collection 对象之前它工作得很好。
下面的例子应该澄清我在这里谈论的内容:
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>
这似乎是一种真正的浪费,因为我必须为每种不同的类型复制完全相同的代码。我想制作一个DoStuff
处理 any的单个实例Collection<T>
,而不是为每个实例制作一个单独的实例。
我试过使用ICollection
,但这有两个问题:第一,ICollection
不暴露.Remove
方法,我不能写foreach
循环,因为我不知道列表中对象的类型。使用更通用的东西,比如object
,不起作用,因为我没有DoStuff
接受的方法object
- 我需要它为实际对象调用适当的方法。编写一个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])
.