C # Общий тип интерфейса, возвращающий Null

Алгоритм углового резания Чайкина может быть идеальным для вас. Для заданного многоугольника с вершинами как P0, P1, ... P (N-1) алгоритм угловой резки будет генерировать две новые вершины для каждого отрезка, определенного P (i) и P (i + 1), как

Q (i) = (3/4) P (i) + (1/4) P (i + 1) R (i) = (1/4) P (i) + (3/4 ) P (i + 1)

Итак, ваш новый многоугольник будет иметь 2N вершин. Затем вы можете снова и снова наносить угловую резку на новый многоугольник до тех пор, пока не будет достигнуто требуемое разрешение. Результатом будет многоугольник со многими вершинами, но при отображении они будут выглядеть гладкими. Можно доказать, что полученная кривая, полученная в результате этого подхода к угловому разрезу, будет сходиться к квадратичной кривой B-сплайна. Преимущество такого подхода заключается в том, что результирующая кривая никогда не будет перевыпускать. Следующие снимки дадут вам лучшее представление об этом алгоритме (снимки, взятые из этой ссылки )

Оригинальный многоугольник Original Polygon [/g2]

Применить угловая резка один раз Apply corner cutting once [/g3]

Применить угловую резку еще раз enter image description here [/g4]

Подробнее см. ссылку для алгоритма углового резания Чайкина

0
задан John Ernest 13 July 2018 в 16:00
поделиться

1 ответ

Решение на самом деле было довольно странным, и спасибо вам, Игорь за то, что помог мне в правильном направлении.

Итак, я изменил свои выходные типы с List<T> на IEnumerable<T> без каких-либо серьезных раздутий в моем коде мой конечный интерфейс выглядел примерно так:

public interface ITable<out T> where T : IEntity {
    string TableName { get; set; }
    Database CurrentDatabase { get; set; }

    T New();
    T Get(ulong id);
    IEnumerable<T> GetAll();

    void LoadAllStorageFiles(IEnumerable<IEntity> storage);
    void StoreAllStorageFiles(IEnumerable<IEntity> storage);
    void LoadRelated(IEntity current);
    void LoadRelated(IEnumerable<IEntity> current);
}

Когда я отделил свои методы Коварианта и инвариантные, первоначально контравариантные, методы на разные типы интерфейсов, ковариант бросил бы и контравариант стал бы null во время трансляции.

Вот что странно, это мои оригинальные контравариантные методы:

    void LoadAllStorageFiles(IEnumerable<T> storage);
    void StoreAllStorageFiles(IEnumerable<T> storage);
    void LoadRelated(T current);
    void LoadRelated(IEnumerable<T> current);

Теперь вы думаете, что сделать типизацию более строгой, чтобы принимать только тот же общий тип, что и остальные из таблицы будет иметь скрытый смысл. В этом случае, однако, во время выполнения это считается контравариантным, и среда выполнения просто сдается и дает вам null без исключения. В этом случае, делая параметры LoadRelated и т. Д. IEntity, а не T, независимо от того, как Twilight Zone'ish в том, что вы теперь сделали его менее строгим, потому что теперь параметр открылся для любой IEntity, что, кажется, я считаю указывают на то, что, возможно, какое-то исключение должно быть сделано гипотетически для среды выполнения в некоторых контравариантных случаях, но, возможно, потребуется больше кода, усилий и денег, чем это стоит для удовлетворения такой проблемы, удовлетворяет проверке среды выполнения, и вы можете двигаться без заминки.

Итак, я только замечаю здесь кого-то, кто сталкивается с этой ситуацией и немного пожимает плечами. Возможно, кто-то может пролить свет на комментарии.

0
ответ дан John Ernest 17 August 2018 в 12:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: