要了解这里发生了什么,您必须意识到 .NET 属性只是一种表示两种不同方法的便捷方式,一种用于获取,另一种用于设置。
也就是说,它们基本上映射了这些操作:
ArrayList m = obj.XmlModulos;
obj.XmlModulos = new ArrayList();
编写更类似于此的代码:
ArrayList m = obj.get_XmlModulos();
obj.set_XmlModulos(new ArrayList());
好的,考虑到这一点,让我们考虑一下您要做什么(这是基于对Timwi 的回答的评论):
obj.XmlModulos.Add(new Modulo());
这真正在做的是:
obj.get_XmlModulos().Add(new Modulo());
考虑到您的get
访问器创建了一个新的ArrayList
,您将永远无法以Modulo
这种方式将 a 添加到您的集合中。您可以这样做的唯一方法是:
ArrayList m = obj.XmlModulos;
m.Add(new Modulo());
obj.XmlModulos = m;
但是,这是实现您的get
和set
访问器的一种非常低效的方法。ArrayList
在每个上创建一个新get
成员并用当前成员填充它modulos
是昂贵的。枚举传递给的任何值set
并将每个值复制到modulos
.
如果有的话,这个类的设计是倒退的(实际上,现在大多数开发人员会建议完全避开这种ArrayList
类型;但如果你坚持,那就是你的决定)。您在IList<Modulo>
内部存储一个(提供类型安全)但在外部公开一个ArrayList
(不提供);这意味着有人可以很容易地尝试将一些非Modulo
类型的随机对象添加到您的列表中,您会得到一个InvalidCastException
. 试图这样做的代码根本不应该编译;这就是泛型的全部意义所在。
好的,我已经说得够多了。我有什么建议?只有一个属于这个类的集合。确定您真正想要提供的功能,并仅公开该功能。不要在两个集合之间来回进行这种昂贵的复制。
例如,如果你真的需要一个ArrayList
,但你只需要启用客户端代码来添加和删除元素到它,然后像这样实现它:
private ArrayList modulos;
public void AddModulo(Modulo m)
{
modulos.Add(m);
}
public bool RemoveModulo(Modulo m)
{
return modulos.Remove(m);
}
这样,即使您在ArrayList
内部使用非泛型(如果您有充分的理由),您仍然可以IList<T>
通过仅允许客户端代码添加和删除该类型的项目来获得有效的类型安全Modulo
。
这可能与实际上对您有意义的解决方案有很大不同。至少,让它有希望地引导你朝着正确的方向前进。