Re[11]: Правильно-ли так реализовать методы сравнения ???
От: samius Япония http://sams-tricks.blogspot.com
Дата: 29.07.10 20:09
Оценка:
Здравствуйте, Аноним, Вы писали:

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


S>>Согласно этой логике нужно наследовать 2х мерную точку от 3х мерной и (N-1)мерную от N-мерной в общем случае.


А>Вы не правы. Наследуясь от 2-х мерной точки вы добавляете ещё одно измерение и она становиться 3-х мерной.


Определитесь с высказываниями. Либо 2-х мерная это 3-х мерная, у которой одна из координат всегда равна 0ю (тогда 2d : 3d), либо 3х мерная это 2х мерная с еще одной координатой, тогда (3d : 2d).

И опишите задачу, где требуется наследование между разномерными точками.
Re[12]: Правильно-ли так реализовать методы сравнения ???
От: Аноним  
Дата: 29.07.10 20:20
Оценка:
Здравствуйте, samius, Вы писали:

В математике, 2-х мерная точка, это 3-х мерная у которой координата по z всегда равна нулю. А одномерной точкой можно считать, точку имеющую только одну координату, а две другие равными нулю. Собственно от этого и отталкиваются в операциях над векторами, считая координату вектора по каждой оси отдельно.

S>>>Согласно этой логике нужно наследовать 2х мерную точку от 3х мерной и (N-1)мерную от N-мерной в общем случае.


С чего вы это взяли. Попробуйте реализовать это. У вас у 2-мерной точки есть два признака координаты x и y, а у 3-х мерной три признака x, y и z. Наследуя признаки 2-мерной и добавляя ещё один признак координату z я получаю класс 3-х мерных точек. Не понимаю чего вам не понятно

S>И опишите задачу, где требуется наследование между разномерными точками.


Задача иллюстрации для которой я его и использовал
Re[13]: Правильно-ли так реализовать методы сравнения ???
От: samius Япония http://sams-tricks.blogspot.com
Дата: 29.07.10 20:29
Оценка:
Здравствуйте, Аноним, Вы писали:

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


А>В математике, 2-х мерная точка, это 3-х мерная у которой координата по z всегда равна нулю.

Это несколько спорное утверждение, и оно имеет мало отношения к определениям точек.
Однако исходя из этого утвреждения 2-х мерная точка есть 3х-мерная (с некоторым условием).

А отношение "это" или "есть" в ООП выражается наследованием, причем "2х мерная это 3х-мерная" выразится как
class point2d : point3d {...}

A> А одномерной точкой можно считать, точку имеющую только одну координату, а две другие равными нулю. Собственно от этого и отталкиваются в операциях над векторами, считая координату вектора по каждой оси отдельно.


кто от этого отталкивается?

S>>>>Согласно этой логике нужно наследовать 2х мерную точку от 3х мерной и (N-1)мерную от N-мерной в общем случае.


А>С чего вы это взяли. Попробуйте реализовать это. У вас у 2-мерной точки есть два признака координаты x и y, а у 3-х мерной три признака x, y и z. Наследуя признаки 2-мерной и добавляя ещё один признак координату z я получаю класс 3-х мерных точек. Не понимаю чего вам не понятно


описал выше. Не понимаю, какие проблемы с реализацией наследования 2х мерной от 3х мерной, кроме нарушения LSP?

S>>И опишите задачу, где требуется наследование между разномерными точками.


А>Задача иллюстрации для которой я его и использовал

Т.е. к математике это отношения не имеет?
Re[9]: Правильно-ли так реализовать методы сравнения ???
От: _FRED_ Черногория
Дата: 29.07.10 20:37
Оценка:
Здравствуйте, Аноним, Вы писали:

_FR>>
  • Идеи наследования 3d точки от 2d точки, как и то, что эти типы являются классами, очень подозрительны. Если пример надуман, то реализации равенства на таком абстрактном примере неинтересна. Если не надуман, то чем оправдан?

    А>В математике, 2-х мерная точка, это 3-х мерная у которой координата по z всегда равна нулю. А одномерной точкой можно считать, точку имеющую только одну координату, а две другие равными нулю. Собственно от этого и отталкиваются в операциях над векторами, считая координату вектора по каждой оси отдельно. Ни что не мешает сделать 5-ти, 6-ти и N-мерную точку, т.к. точка это просто абстракция, а смысл в неё залить можно какой угодно. Например, такие многомерные пространства(из точек) часто используются в физике. А в теории суперструн, которая претендует сейчас на звание теории всего, многие исследуемые объекты имеют по 10-12 измерений.


    Вы слышали про задачу на наследование квадрата от прямоугольника или прямоугольника от квадрата? Если уж проводить аналогии с математикой до конца, то используйте вектор и одного, двух, трёх элементов и так далее. Никакого отношения "родитель"-"потомок" между ними нет и придумывать её не надо.

    _FR>>Не могли бы сравнить свой решение с тем и объяснить, чем ваше решение вам нравится больше?

    А>Что-бы разговор был более предметным так [1] я буду помечать в тексте вопросы на которые хотелось бы получить ответы

    хОКкей

    А>Мысль о применении сторонних компараторов посетила сразу, но с толку сбил класс ComparerBuilder<T>. Я не знал его реализации и не сразу сообразил, что именно он делает. [1]Если я правильно понял, то Вы считаете, что такая реализация будет более правильной:


    Не совсем. Компараторы в топку. Интересными для нас являются методы TwoDPoint::Equals(TwoDPoint), TwoDPoint::GetHashCode() и TwoDPoint::CompareTo(TwoDPoint). Давайте пока откажемся от идеи наследования, но TwoDPoint оставил классом. Считаем, что он sealed и неизменяем. Тогда должны будем получить вот что:
    public bool Equals(TwoDPoint other) {
      return other != null
        && x == other.x
        && y == other.y;
    }
    
    public override int GetHashCode() {
      return x ^ y;
    }
    
    public int CompareTo(TwoDPoint other) {
      if(other == null) {
        return 1;
      }//if
    
      var compare = x - other.x;
      if(compare != 0) {
        return compare;
      }//if
    
      return y - other.y;
    }


    Я не знаю, как проще написать то, что нам требуется.

    А>Однако меня волнует один момент. Если нарисовать схему вызовов:

    А>operator!=(T,T) -> operator==(T,T) -> Equals(object) -> Equals(T) -> EqualityComparer
    А>CompareTo(T) -> Comparer


    Не нужно рассматривать такие схемы. Я пока что не вижу, что наследование вообще в данном случае зачем-то нужно.

    А>[2] Я просто не понимаю, почему если метод CompareTo(object) и сторонний компаратор делают одно и то-же, почему нельзя всё замкнуть на CompareTo(object) если всё равно нет разницы


    Во-первых, CompareTo(object) у меня нет. Вы его сами себе вводите, а у меня потом спрашиваете, что с ним не так. Не буду отвечать. Если бы мне понадобился бы такой метод, то выглядел бы он так:
    public int CompareTo(object other) {
      return CompareTo(other as TwoDPoint);
    }

    то есть в моём понимании вопроса интересен метод CompareTo(TwoDPoint), код которого приведён выше. Ваши же все неприятности и непонимания из-за того, что вы пытаетесь реализовать наследование. Не нужно. Научитесь сначала просто реализовывать равенства для неизменяемых структур и sealed-классов.

    Поэтому остальные вопросы я опущу: они так же связаны с наследованием. Для реализации наследования в иерархии классов требуется в первую очередь чёткое представление о том, как должны сравниваться объекты различных классов — могут ли они быть равны или не могут (пока что у вас точка [0, 0] равна получается точке [0, 0, 500])? Второе: для корректной реализации сравнения иерархия классов должна быть замкнутой (то есть внешний код не может подкинуть вам "наследничка"), иначе невозможно гарантировать то, что ваш алгоритм сравнения всегда будет корректен. Поэтому предлагаю для начала чтко определиться с тем, что мы делаем (какого рода сравнения нам требуются), а потом уже приступим к реализации.

    Почитайте внимательно ещё раз (если требуется) всё, что я вам тут (во всё треде) написал и ответьте на мои вопросы "зачем вам то" да "для чего это". Итак: необходимость наследования я вижу высосана из пальца или взята из неверных представлении об ООП. желание написать один метод Compare вместо разделения Equals\Compare. Необходимость использования класса вытекает только лишь из желания унаследоваться или есть ещё какие причины? Нужно ли уметь сравнивать 2d и 3d точки и какова таблица истинности для этих операций?
  • Help will always be given at Hogwarts to those who ask for it.
    Re[11]: Правильно-ли так реализовать методы сравнения ???
    От: _FRED_ Черногория
    Дата: 29.07.10 20:42
    Оценка:
    Здравствуйте, Lloyd, Вы писали:

    _FR>>Потому что, если сделать без такого билдера на Func<>, напрямую сравнив поля, то код будет работать потенциально сильно быстрее. С компиляцией выражений в код разницы практически никакой.

    L>>>а работа с MemberExpression — нет?
    _FR>>Потому что "работа с MemberExpression" идёт только во время вызова Add. Один раз. При вызове To[…]Comparer() создаётся компаратор с уже скомпилированными методами, внутри которого никаких преобрахований типов и никакого рефлекшена нет — как будто код написан непосредственно в коде класса.
    L>Т.е. речь прежде всего о перформансе? Тогда выбор понятен.

    Именно. А чем ещё можно обосновать такое? ИМХО, удобство написания, экономия нажатий на клавиши и надёжность рефакторинга (то, что даёт билдер), которее просаживает производительность в сотни, если не больше, раз, никому даром небыло бы нужно и, ИМХО, больше смахивает на желание покрасоваться "о как я умею". Небыло бы expressions я бы предпочёл ручное набивание / кодогенерацию на крайняк таким вот "улучшайзерам" на делегатах.
    Help will always be given at Hogwarts to those who ask for it.
    Re[10]: Правильно-ли так реализовать методы сравнения ???
    От: Аноним  
    Дата: 30.07.10 11:02
    Оценка:
    Здравствуйте, _FRED_, Вы писали:

    _FR>Вы слышали про задачу на наследование квадрата от прямоугольника или прямоугольника от квадрата? Если уж проводить аналогии с математикой до конца, то используйте вектор и одного, двух, трёх элементов и так далее. Никакого отношения "родитель"-"потомок" между ними нет и придумывать её не надо.


    Пожалуйста:
            class Rectangle
            {
                public Rectangle(uint width, uint height)
                {
                    Width = width;
                    Height = height;
                }
    
                public virtual uint Width { get; set; }
                public virtual uint Height { get; set; }
    
                public uint Area() { return Width * Height; }
            }
    
            class Square : Rectangle
            {
                public Square(uint size)
                    : base(size, size) { }
    
                public override uint Width
                {
                    get { return base.Width; }
                    set { base.Width = base.Height = value; }
                }
    
                public override uint Height
                {
                    get { return base.Height; }
                    set { base.Height = base.Width = value; }
                }
            }
    
            static void Main()
            {
                Rectangle rect = new Rectangle(10, 20);
                Console.WriteLine("Rectangle area : {0}", rect.Area());
    
                Square square = new Square(20);
                Console.WriteLine("Square area : {0}", square.Area());
            }


    _FR>Я не знаю, как проще написать то, что нам требуется.

    _FR>Не нужно рассматривать такие схемы. Я пока что не вижу, что наследование вообще в данном случае зачем-то нужно.
    _FR>Поэтому остальные вопросы я опущу: они так же связаны с наследованием.

    Вообще то, я весьма красноречиво написал: "Поэтому решил для иллюстрации написать классы попроще..."

    _FR>Во-первых, CompareTo(object) у меня нет. Вы его сами себе вводите, а у меня потом спрашиваете, что с ним не так. Не буду отвечать.


    Ну уберите CompareTo(object) проблему это не изменит, ваши вызовы НЕ виртуальные.

    Второе: для корректной реализации сравнения иерархия классов должна быть замкнутой (то есть внешний код не может подкинуть вам "наследничка"), иначе невозможно гарантировать то, что ваш алгоритм сравнения всегда будет корректен.

    А почему тогда большинство классов .NET не запечатаны и позволяют наследоваться?

    Поэтому предлагаю для начала чётко определиться с тем, что мы делаем (какого рода сравнения нам требуются), а потом уже приступим к реализации.

    Да не чего тут определяться это просто иллюстрация, чтобы не городить огород с большими классами.

    _FR>Итак: необходимость наследования я вижу высосана из пальца или взята из неверных представлении об ООП.


    Необходимость наследования, как я уже говорил, высосана из необходимости проиллюстрировать проблему на максимально простом примере.
    Re[11]: Правильно-ли так реализовать методы сравнения ???
    От: _FRED_ Черногория
    Дата: 30.07.10 11:39
    Оценка:
    Здравствуйте, Аноним, Вы писали:

    _FR>>Вы слышали про задачу на наследование квадрата от прямоугольника или прямоугольника от квадрата? Если уж проводить аналогии с математикой до конца, то используйте вектор и одного, двух, трёх элементов и так далее. Никакого отношения "родитель"-"потомок" между ними нет и придумывать её не надо.


    А>Пожалуйста:


    Я спросил "слышали ли вы про задачу", а не привести её решение. Ясно: если слышали, то решения не знаете.

    _FR>>Я не знаю, как проще написать то, что нам требуется.

    _FR>>Не нужно рассматривать такие схемы. Я пока что не вижу, что наследование вообще в данном случае зачем-то нужно.
    _FR>>Поэтому остальные вопросы я опущу: они так же связаны с наследованием.

    А>Вообще то, я весьма красноречиво написал: "Поэтому решил для иллюстрации написать классы попроще..."


    Ну и что я должен тогда думать?

    _FR>>Во-первых, CompareTo(object) у меня нет. Вы его сами себе вводите, а у меня потом спрашиваете, что с ним не так. Не буду отвечать.


    А>Ну уберите CompareTo(object) проблему это не изменит, ваши вызовы НЕ виртуальные.


    В этом их преимущество.

    А>Второе: для корректной реализации сравнения иерархия классов должна быть замкнутой (то есть внешний код не может подкинуть вам "наследничка"), иначе невозможно гарантировать то, что ваш алгоритм сравнения всегда будет корректен.

    А>А почему тогда большинство классов .NET не запечатаны и позволяют наследоваться?

    А в этих классах реализована своя логика сравнения?

    А>Поэтому предлагаю для начала чётко определиться с тем, что мы делаем (какого рода сравнения нам требуются), а потом уже приступим к реализации.

    А>Да не чего тут определяться это просто иллюстрация, чтобы не городить огород с большими классами.

    Я уже выше отвечал на это: "Если пример надуман, то реализации равенства на таком абстрактном примере неинтересна." Если не хотите постапать так, как велит Howtoask и продолжаете настаивать на помощи в искусственных примерах, я вас оставлю.

    _FR>>Итак: необходимость наследования я вижу высосана из пальца или взята из неверных представлении об ООП.

    А>Необходимость наследования, как я уже говорил, высосана из необходимости проиллюстрировать проблему на максимально простом примере.

    А какую проблему-то? Если вы не постараетесь быть точным в своих формулировках, то я никогда не пойму, что же вам следует ответить. Прежде чем спросить, подумайте, можно ли как-то превратно истолковать ваши слова или нет.
    Help will always be given at Hogwarts to those who ask for it.
    Re[8]: Правильно-ли так реализовать методы сравнения ???
    От: samius Япония http://sams-tricks.blogspot.com
    Дата: 30.07.10 18:31
    Оценка:
    Здравствуйте, _FRED_, Вы писали:

    _FR>

    Нашел, откуда ветер дует
    http://msdn.microsoft.com/en-us/library/ms173147(VS.80).aspx
    Re[9]: Правильно-ли так реализовать методы сравнения ???
    От: _FRED_ Черногория
    Дата: 30.07.10 18:38
    Оценка:
    Здравствуйте, samius, Вы писали:

    _FR>>[*]Идеи наследования 3d точки от 2d точки, как и то, что эти типы являются классами, очень подозрительны. Если пример надуман, то реализации равенства на таком абстрактном примере неинтересна. Если не надуман, то чем оправдан?


    S>Нашел, откуда ветер дует

    S>http://msdn.microsoft.com/en-us/library/ms173147(VS.80).aspx

    Даже как-то обидно, что столько времени и слов потрачено ради разбора показательного (в плохом смысле) примера из МСДН
    Help will always be given at Hogwarts to those who ask for it.
    Re[10]: Правильно-ли так реализовать методы сравнения ???
    От: samius Япония http://sams-tricks.blogspot.com
    Дата: 30.07.10 18:44
    Оценка:
    Здравствуйте, _FRED_, Вы писали:

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


    S>>Нашел, откуда ветер дует

    S>>http://msdn.microsoft.com/en-us/library/ms173147(VS.80).aspx

    _FR>Даже как-то обидно, что столько времени и слов потрачено ради разбора показательного (в плохом смысле) примера из МСДН


    Там в комментах есть еще показательный пример на тему, не затронутую в этом топике:
    object x = new TwoDPoint(1, 2);
    object y = new ThreeDPoint(1, 2, 3);
    y.Equals(x); // Returns false
    x.Equals(y); // Returns true(!)
    Re[11]: Правильно-ли так реализовать методы сравнения ???
    От: _FRED_ Черногория
    Дата: 30.07.10 18:45
    Оценка:
    Здравствуйте, samius, Вы писали:

    S>>>Нашел, откуда ветер дует

    S>>>http://msdn.microsoft.com/en-us/library/ms173147(VS.80).aspx

    _FR>>Даже как-то обидно, что столько времени и слов потрачено ради разбора показательного (в плохом смысле) примера из МСДН


    S>Там в комментах есть еще показательный пример на тему, не затронутую в этом топике:

    S>object x = new TwoDPoint(1, 2);
    S>object y = new ThreeDPoint(1, 2, 3);
    S>y.Equals(x); // Returns false
    S>x.Equals(y); // Returns true(!)


    Ой, да каких только ужасов можно наповыдумывать на больную-то голову?
    Help will always be given at Hogwarts to those who ask for it.
    Re[12]: Правильно-ли так реализовать методы сравнения ???
    От: samius Япония http://sams-tricks.blogspot.com
    Дата: 30.07.10 19:04
    Оценка:
    Здравствуйте, _FRED_, Вы писали:

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


    S>>Там в комментах есть еще показательный пример на тему, не затронутую в этом топике:

    _FR>
    S>>object x = new TwoDPoint(1, 2);
    S>>object y = new ThreeDPoint(1, 2, 3);
    S>>y.Equals(x); // Returns false
    S>>x.Equals(y); // Returns true(!)
    _FR>


    _FR>Ой, да каких толимько ужасов можно наповыдумывать на больную-то голову?


    Что значит понавыдумывать? Это реальное такое следствие у примера из гайдлайна MSDN...

    А хуже того —
    new []{new TwoDPoint(1, 2) }.Contains(new ThreeDPoint(1, 2, 3));


    Я не возьмусть предположить, что вернет это выражение, true или false, потому как не знаю, что с чем будет сравниваться.
    Re[10]: Правильно-ли так реализовать методы сравнения ???
    От: Аноним  
    Дата: 31.07.10 11:40
    Оценка:
    Здравствуйте, _FRED_, Вы писали:

    Ну в общем я переварил вроде всё, что вы мне тут написали. Спасибо за старание

    _FR>Второе: для корректной реализации сравнения иерархия классов должна быть замкнутой (то есть внешний код не может подкинуть вам "наследничка"), иначе невозможно гарантировать то, что ваш алгоритм сравнения всегда будет корректен.


    Но вот это замечание, затронуло меня до глубины души. Вы не могли бы привести пример, как в НЕ замкнутой иерархии классов алгоритм сравнения полетел к чертям. Ещё был бы благодарен если-бы выкинули часть кода метода Add в вашем ComparerBuilder, очень уж интересно посмотреть. Спасибо
    Re[11]: Правильно-ли так реализовать методы сравнения ???
    От: _FRED_ Черногория
    Дата: 31.07.10 20:08
    Оценка:
    Здравствуйте, Аноним, Вы писали:

    А>Ну в общем я переварил вроде всё, что вы мне тут написали. Спасибо за старание


    _FR>>Второе: для корректной реализации сравнения иерархия классов должна быть замкнутой (то есть внешний код не может подкинуть вам "наследничка"), иначе невозможно гарантировать то, что ваш алгоритм сравнения всегда будет корректен.


    А>Но вот это замечание, затронуло меня до глубины души. Вы не могли бы привести пример, как в НЕ замкнутой иерархии классов алгоритм сравнения полетел к чертям.


    Зачем? Вы можете привести такой вариант, который не полетит к чертям? Нука-нука? Вы кажется не совсем всй переварили: я же точно говорил о том, что что бы говорить о реализации сравнения в какой-либо иерархии надо иметь на руках таблицу истинности. А как вы сможете построить таблицу истинности чего-то конкретного (базового класса) с неихвестно с чем? Только строго ограничив то, как наследник может реализовывать операцию сравнения. Но, во-первых, это невозможно проверить, а, во-вторых, это может сильно ограничить наследника в его правах. Так-то.
    Help will always be given at Hogwarts to those who ask for it.
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.