Показать сообщение отдельно
Старый 06.11.2024, 18:25   #12  
Товарищ ♂uatr is offline
Товарищ ♂uatr
Участник
Аватар для Товарищ ♂uatr
MCBMSS
 
310 / 873 (30) +++++++
Регистрация: 23.10.2012
Привет.
Не уверен насколько удачно выбрал тему для подобного текста.

Есть кастомизация - некий фремворк позволяющий выстраивать событийную модель (по мотивам 365).
Стандартно: Есть генератор события - некий объект. Есть подписчики - тоже объекты.
Список подписчиков должен где-то храниться и исторически так сложилось, что это Set.
Всё бы хорошо, да, как принято, в какой-то момент, какой-то там из "генераторов" начал считать сводный hash на основании какой-то информации предоставляемой его подписчиками (описание по верхам).
Подписчики, в данном случае, N экземпляров 1-го класса инициализированные с уникальными параметрами.
Упрощенный пример:
X++:
subscriber.add(new Subs(param_1)); 
subscriber.add(new Subs(param_2));
Проблема в том, что сводный hash чувствителен к последовательности. Она, как оказалось, "пляшет". Не смотря на то, что код формирования списка подписчиков никакой динамики не содержит.
Просто иногда функция getEnumerator возвращает последовательность:
{Subs(param_1), Subs(param_2)}, а иногда {Subs(param_2), Subs(param_1)}

Легко воспроизводится в джобе (несколько раз вызвать придётся):
X++:
Set           s = new Set(Types::Class);
SetEnumerator se;
;

s.add(new Class1(5));
s.add(new Class1(1));

se = s.getEnumerator();

while (se.moveNext())
{
    info(se.current().toString());
}
где Class1:
X++:
class Class1
{
    int j;
    
    public void new(int _j = 0)
    {
        ;
        
        j = _j;
    }

    public str toString()
    {
        ;
        
        return int2str(j);
    }
}
Set - отсортированный список (The Set class is used for the storage and retrieval of data from a collection in which the values of the elements contained are unique and serve as the key values according to which the data is automatically ordered)
Отсюда возникает вопрос, критерий сортировки массива классов какой?
Спасибо MS, Set это
X++:
public class Set : Microsoft.Dynamics.Ax.Xpp.XppObjectBase
Ну и если поисследовать вопрос детальнее это обёртка над .Net классами:
X++:
switch (_Type)
{
case Types.String:
case Types.RString:
case Types.VarString:
	this.set = new SortedSet<object>(CollectionComparerString.Default);
	return;
case Types.Integer:
case Types.Enum:
case Types.Time:
	this.set = new SortedSet<object>(CollectionComparerInt.Default);
	return;
case Types.Real:
	this.set = new SortedSet<object>(CollectionComparerReal.Default);
	return;
case Types.Date:
	this.set = new SortedSet<object>(CollectionComparerDate.Default);
	return;
case Types.UtcDateTime:
	this.set = new SortedSet<object>(CollectionComparerDateTime.Default);
	return;
case Types.Container:
	this.set = new SortedSet<object>(CollectionComparerContainer.Default);
	return;
case Types.Record:
	this.set = new SortedSet<object>(CollectionComparerRecord.Default);
	return;
case Types.Class:
	this.set = new HashSet<object>();
	return;
case Types.Guid:
	this.set = new SortedSet<object>(CollectionComparerGuid.Default);
	return;
case Types.Int64:
	this.set = new SortedSet<object>(CollectionComparerInt64.Default);
	return;
}
this.set = new SortedSet<object>(CollectionComparer.Default);
Соответственно, в моём случае интересен:
X++:
this.set = new HashSet<object>();
Эта "штука" в итоге вызывает виртуальный метод "GetHashCode" Object'a через EqualityComparer (матрёшка), который, исходя из того, что он виртуальный, можно перекрыть, но...то-то не "взлетает"
За это сообщение автора поблагодарили: Logger (7), sukhanchik (5).