0

我有以下领域:

private IList<Modulo> modulos;

和以下属性:

    public virtual ArrayList XmlModulos
    {
        get
        {
            if (modulos == null) return new ArrayList();
            var aux = new ArrayList();
            foreach (Modulo m in modulos)
                aux.Add(m);
            return aux;
        }
        set
        {
            modulos = new List<Modulo>();
            foreach (object o in value)
                modulos.Add((Modulo)o);
        }

    }

get 完美运行,因为我有另一个用于不同目的的直接属性。但是该设置不起作用,因为当我使用此属性时,它不会更新任何内容。调试表明该属性是一个空的 ArrayList(计数 0)并且该字段保持为空。知道为什么这不起作用吗?任何帮助将不胜感激。

4

2 回答 2

1

要了解这里发生了什么,您必须意识到 .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;

但是,这是实现您的getset访问器的一种非常低效的方法。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

这可能与实际上对您有意义的解决方案有很大不同。至少,让它有希望地引导你朝着正确的方向前进。

于 2010-08-22T05:40:19.293 回答
0

我无法重现您的问题;我复制了你的代码,然后执行了这一行:

XmlModulos = new ArrayList { new Modulo() };

在此之后,调试器和Console.WriteLine报告都modulos.Count和.XmlModulos.Count1

因此,错误在于您没有向我们展示的其他代码。

于 2010-08-22T04:53:02.467 回答