Информация об изменениях

Сообщение Re[2]: Вариантность от 02.02.2018 15:11

Изменено 02.02.2018 16:22 gamburger

Re[2]: Вариантность
Здравствуйте, Qbit86, Вы писали:

Q>Здравствуйте, gamburger, Вы писали:


G>>Моя схема со всеми ее констрейнтами нарушает какой-то здравый смысл или логику (тогда каким образом оно нарушается)?


Q>Похоже, нарушается ко-/контравариантность. Погугли про ключевые слова in/out в generic'ах в контексте covariance/contravariance, в каком направлении меняется вариантность входных и выходных параметров функций.


Я уже пробовал делать параметр интерфейса ковариантным или контравариантным.
public interface IEatableBy<in TEater>
и
public interface IEatableBy<in TEater>

В случае с in ничего не меняется, в случае с out ошибка с TVictim остается, но ошибка с TEater пропадает (зато появляется другая ошибка, что в методе BeEatenBy параметр TEater не может быть входящим, но с этим все понятно).

Если рассмотреть схему на примере на примере Хищника и Тревоядного, то:
1)
        public class Predator: Animal<Herbivore>

следовательно
2)
    public abstract class Animal<Herbivore>
            //моя жертва съедаема мной самим
            where Herbivore: IEatableBy<Animal<Herbivore>>

следовательно
3)
    public interface IEatableBy<Animal<Herbivore>> 
        where TEater: Animal<IEatableBy<Animal<Herbivore>>>

идем обратно в анимал:
4)
    public abstract class Animal<IEatableBy<Animal<Herbivore>>>
            //моя жертва съедаема мной самим
            where IEatableBy<Animal<Herbivore>>: IEatableBy<Animal<IEatableBy<Animal<Herbivore>>>>

потом идем дальше обратно в IEatableBy и т.д.
То есть тут видно, что 2) отличается от 4) , но мой мозг слишком слаб, чтобы самому понять, что именно тут не так. Но я хочу это наконец понять, т.к. уже не первый раз попадаю в такую лапшу с генериками. Может, кто-нить поймет, что там происходит, из-за чего не компилится, и что можно сделать, чтобы получиться компилящийся код, при этом чтобы хищники не могли есть растения.
Re[2]: Вариантность
Здравствуйте, Qbit86, Вы писали:

Q>Здравствуйте, gamburger, Вы писали:


G>>Моя схема со всеми ее констрейнтами нарушает какой-то здравый смысл или логику (тогда каким образом оно нарушается)?


Q>Похоже, нарушается ко-/контравариантность. Погугли про ключевые слова in/out в generic'ах в контексте covariance/contravariance, в каком направлении меняется вариантность входных и выходных параметров функций.


Я уже пробовал делать параметр интерфейса ковариантным или контравариантным.
public interface IEatableBy<in TEater>
и
public interface IEatableBy<in TEater>

В случае с in ничего не меняется, в случае с out ошибка с TVictim остается, но ошибка с TEater пропадает (зато появляется другая ошибка, что в методе BeEatenBy параметр TEater не может быть входящим, но с этим все понятно).

Если рассмотреть схему на примере на примере Хищника и Тревоядного, то:
1)
        public class Predator: Animal<Herbivore>

следовательно
2)
    public abstract class Animal<Herbivore>
            //моя жертва съедаема мной самим
            where Herbivore: IEatableBy<Animal<Herbivore>>

следовательно
3)
    public interface IEatableBy<Animal<Herbivore>> 
        where Animal<Herbivore>: Animal<IEatableBy<Animal<Herbivore>>>

идем обратно в анимал:
4)
    public abstract class Animal<IEatableBy<Animal<Herbivore>>>
            //моя жертва съедаема мной самим
            where IEatableBy<Animal<Herbivore>>: IEatableBy<Animal<IEatableBy<Animal<Herbivore>>>>

потом идем дальше обратно в IEatableBy и т.д.
То есть тут видно, что 2) отличается от 4) , но мой мозг слишком слаб, чтобы самому понять, что именно тут не так. Но я хочу это наконец понять, т.к. уже не первый раз попадаю в такую лапшу с генериками. Может, кто-нить поймет, что там происходит, из-за чего не компилится, и что можно сделать, чтобы получиться компилящийся код, при этом чтобы хищники не могли есть растения.