Неверное приведение в C5.IPriorityQueueHandle

У меня проблемы с реализацией интерфейса C5.IPriorityQueueHandle с C5 IntervalHeap. Я могу использовать кучу отлично с нулевыми дескрипторами, используя DeleteMin() по умолчанию и т. Д., Но я хочу иметь возможность обновлять приоритет дескриптором позже.

Ниже приведена упрощенная версия моего кода вместе с текстом исключения:

Исключение: необработанное исключение типа "System.InvalidCastException" произошло в C5.dll

Дополнительная информация: Невозможно привести объект типа "Handle`1[_8_Puzzle.Node]" к типу "Handle[_8_Puzzle.Node]".

public class Node : IComparable<Node>
{
    public Board board;
    public Handle<Node> handle;
    public Node(Board b)
    {
        this.board = b;
        this.handle = new Handle<Node> (b.Id);
    }

    ...
}

public class Handle<Node> : C5.IPriorityQueueHandle<Node>
{
    private int id;

    public Handle(int id)
    {
        this.id = id;
    }
}

static void doWork(Node rootNode)
    {
        C5.IntervalHeap<Node> q = new C5.IntervalHeap<Node>();
        q.Add(rootNode); //works fine, handle is null

        ...

        Board child = getChild(rootNode);

        if (someConditionIsMet) {

            Node childNode = new Node(child);
            C5.IPriorityQueueHandle<Node> h = (C5.IPriorityQueueHandle<Node>)(childNode.handle);
            q.Add(ref h, childNode); //breaking line!

        }
    }

1 ответ

Решение

Вы используете дескрипторы с библиотекой C5 неправильно.

Из документации C5 для handle параметр C5.IntervalHeap<T>.Add метод (акцент мой):

На выходе: ручка для добавленного элемента. На входе: null для размещения нового дескриптора, недопустимый дескриптор для повторного использования. Дескриптор для повторного использования должен быть совместим с этой очередью приоритетов, поскольку он создается очередью приоритетов того же типа времени выполнения, но не обязательно тем же объектом очереди приоритетов.

Вы не передаете дескриптор, созданный приоритетной очередью. Вы передаете в свои собственные ручки, которые вы создаете в Node конструктор класса.

Не создавайте свою собственную реализацию IPriorityQueueHandle<T>; вместо этого полагайтесь на любые объекты-дескрипторы, которые вы получите от C5. Я бы порекомендовал вам изменить тип handle поле внутри Node в IPriorityQueueHandle<Node>не инициализируйте его в Node конструктор, и измените вызов на ломающей линии на

        q.Add(ref childNode.handle, childNode);

Строка до, где вы назначаете переменную h, могут быть удалены, как и ваш Handle<T> учебный класс.

Другие вопросы по тегам