为什么我需要重新引用库中的主要更改dll

时间:2014-05-30 07:09:33

标签: c# .net indexer

我在我的库Base.dll中实现了一个索引器

namespace Base
{
public class BOCollection<TKey, TValue> : Dictionary<TKey, TValue>
{
    public BOCollection() : base() { }
    public BOCollection(int capacity) : base(capacity) { }
    public BOCollection(IEqualityComparer<TKey> comparer) : base(comparer) { }
    public new TValue this[TKey key]
    {
        get
        {
            lock(this)
            {
                return base[key];
            }
        }
        set
        {
            lock(this)
            {
                base[key] = value;
            }
        }
    }
}
}

现在这个更改迫使我重新编译或重新引用所有其他库中的Base.dll。 我清理了我的网络应用程序,但问题仍然存在。 我收到错误: 找不到方法:'System.Collections.Generic.Dictionary`2 Base.get_Child()'。

但是一旦我在项目中重新引用Base.dll给出错误它就得到了修复。现在我有15个不同的库,其中引用了这个dll。 你能说出我做错了吗? 应用程序基于.Net 4.0

注意:我从头开始有这个属性

public  Dictionary<string,Base> Child {
        get { return _Child = _Child ?? new Dictionary<string, Base>(StringComparer.OrdinalIgnoreCase); }
      set { _Child = value; }
    }
    protected Dictionary<string, Base> _Child;

现在我改变了这个

 public BOCollection<string, Base> Child
    {
        get { return _Child = _Child ?? new BOCollection<string, Base>(StringComparer.OrdinalIgnoreCase); }
        set { _Child = value; }
    }
    protected BOCollection<string, Base> _Child;

2 个答案:

答案 0 :(得分:3)

您的代码有许多不同的问题,如果没有对依赖程序集进行一些更改,就无法修复它。

首先,您已经更改了合约(Child属性的返回类型已更改),因此您应该更改程序集版本并针对新程序集重新编译依赖项。

其次,您已将索引器隐藏在派生类中。这是行不通的,因为这意味着当您在代码中专门引用BOCollection时,索引器仅用于 。这意味着如果您不更改代码,则100%的代码将使用具有lock的版本。这是非常不安全的设计!

第三,使用ConcurrentDictionary。它为您提供了开箱即用的字典值的线程安全访问:)

你不会避免重新编译所有依赖程序集,就这么简单。现在,如果您对将来的校对感兴趣,这正是您希望用作小型接口的原因之一。例如,不要使用Dictionary<string, Base>作为返回类型,而是使用IDictionary<string, Base>。这使您可以自由地更改内部实现而无需更改合同,从而破坏DLL兼容性。

更改程序集而不必重新编译其依赖项的唯一安全方法是避免任何可能会破坏的更改。例如:

  • 更改const或efault方法参数值 - 总是一个坏主意,因为它们是在编译时进行评估的。
  • 删除publicprotected成员
  • 更改方法和属性的返回类型或参数

可以做出一些改变,但是:

  • 添加新方法重载和新成员
  • 添加新类型
  • 几乎更改任何代码 - 重要的是不要更改现有的定义(即便如此,只有那些public和{{1在某些情况下protected)。

即便如此,我也会提出反对意见。简单地保持所有内容同步和版本化通常是一个更好的主意。它可以为您节省很多麻烦。

答案 1 :(得分:1)

这里的问题不在于您添加了索引器,问题是您删除了正在其他程序集中使用的属性。

那些其他程序集仍然有代码打算调用Child属性的getter,但是因为你删除了它,那个getter方法不再存在,这就是你得到那个错误的原因。