Здравствуйте, Pek2014, Вы писали:
P> В обычном Dictionary<> не устраивает реализация метода Add. Надо кое-что в него добавить (некую диагностику).
Почему в этот метод? Словарь — это что-то низкоуровневое (по-сути примитив типа массива). О какой именно диагностике идет речь? Отладке?
Вы уже предложили extension method, тоесть думаете в правильном направлении. Добавляйте что там вам необходимо в методы, которые используют какойто определенный экземпляр словаря (а не все подряд). Можно перед каждым вызовом (удобнее всего с помочью extension method). Отговорки в стиле "надо править слишком большое число мест" звучат не очень убедительно, ведь именно так подобная задача и решается, переопределить невертуальный метод — звучит как XY проблема.
Задачка. В обычном Dictionary<> не устраивает реализация метода Add. Надо кое-что в него добавить (некую диагностику). В остальном стандартный Dictionary<> вполне устраивает.
Унаследоваться и переопределить метод Add не выходит. Метод не виртуальный. Видится два выхода:
Выход 1. Написать свой новый внешний статический метод (например AddValue) и заменить все вызовы старого Add на новый AddValue (можно сделать как extention метод для красоты).
Выход 2. Написать свой Dictionary агрегировав стандартный и тупо перенаправив ему все вызовы, подкрутив немного метод Add.
Выход 1 не устраивает тем, что надо поправить очень большое число мест использования привычного метода Add на нестандартный.
Выход 2 Хорош тем, что требует исправления клиентского кода только в месте создания словаря, а код в местах его использования не меняется. Но плох тем, что надо написать кучу тупого кода, повторяя вполне устраивающую функциональность стандартного словаря.
Нет ли ещё какого способа "переопределить" невиртуальный метод?
QL>В клиентском коде использовать через IDictionary.
Да. Но теперь надо заставить (убедиться, быть уверенным что...) пользоваться только IDictionary?
Просматривать и анализировать код — это не метод. Что нибудь да пропустим...
Вот такой вариант... странноватый?...
public class MyDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IDictionary<TKey, TValue>
{
public new void Add(TKey key, TValue val)
{
// ...base.Add(key, val);
// ...
}
public static IDictionary<TKey, TValue> Create() => new MyDictionary<TKey, TValue>();
public static IDictionary<TKey, TValue> Create(int capacity) => new MyDictionary<TKey, TValue>(capacity);
public static IDictionary<TKey, TValue> Create(IEqualityComparer<TKey> comparer) => new MyDictionary<TKey, TValue>(comparer);
public static IDictionary<TKey, TValue> Create(IDictionary<TKey, TValue> dictionary) => new MyDictionary<TKey, TValue>(dictionary);
public static IDictionary<TKey, TValue> Create(int capacity, IEqualityComparer<TKey> comparer) => new MyDictionary<TKey, TValue>(capacity, comparer);
public static IDictionary<TKey, TValue> Create(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer) => new MyDictionary<TKey, TValue>(dictionary, comparer);
private MyDictionary() { }
private MyDictionary(int capacity) : base(capacity) { }
private MyDictionary(IEqualityComparer<TKey> comparer) : base(comparer) { }
private MyDictionary(IDictionary<TKey, TValue> dictionary) : base(dictionary) { }
private MyDictionary(int capacity, IEqualityComparer<TKey> comparer) : base(capacity, comparer) { }
private MyDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer) : base(dictionary, comparer) { }
}
...
var mydic = MyDictionary<string, string>.Create();
mydic.Add("a", "123");
...
Здравствуйте, Sinatr, Вы писали:
P>> В обычном Dictionary<> не устраивает реализация метода Add. Надо кое-что в него добавить (некую диагностику).
S>Вы уже предложили extension method... Отговорки в стиле "надо править слишком большое число мест" звучат не очень убедительно, ведь именно так подобная задача и решается,
Задача в том, чтобы программист, получивший ссылку на словарь действовал "как обычно", "как привычно", ничего не подозревая, но из-за фокуса сделанного в момент создания словаря (где-то далеко по коду), результат был бы "особенный".
S>...переопределить невиртуальный метод — звучит как XY проблема.
И тем не менее это сделать удалось с помощью повторной реализации интерфейса.
А доступ к старой версии метода (тому, что был перед переопределением),удалось (пришлось) блокировать запретом прямого создания экземпляров класса и предоставлением конкретной фабрики.
Здравствуйте, Pek2014, Вы писали:
P>Выход 1. Написать свой новый внешний статический метод (например AddValue) и заменить все вызовы старого Add на новый AddValue (можно сделать как extention метод для красоты). P>Выход 2. Написать свой Dictionary агрегировав стандартный и тупо перенаправив ему все вызовы, подкрутив немного метод Add.
Если там где он используется код не time-critical с кучей вызовов за короткое время то второй вариант в поддержке будет удобнее. Хотя все равно придется следить чтобы не создавали стандартный Dictionary.