Re[6]: IEquatable<T>
От: Qbit86 Кипр
Дата: 11.01.17 08:32
Оценка: -1 :)
Здравствуйте, vdimas, Вы писали:

Q>>Не паясничай, речь шла
Автор: Qbit86
Дата: 10.01.17
про `GenericEqualityComparer<T>`:

V>Который не умеет вызывать operator==? ))

А зачем его вызывать? Алгоритмы и коллекции стандартной библиотеки работают через компараторы, они не используют `operator ==`. Ты и этого не знал? Это легко проверить: для кастомного класса или структуры определи `operator ==` бросающим исключение:
using System;
using System.Collections.Generic;

internal struct /* or sealed class */ IntWrapper : IEquatable<IntWrapper>
{
    public IntWrapper(int i)
    {
        Value = i;
    }

    public int Value { get; }

    public bool Equals(IntWrapper other) => Value == other.Value;

    public override int GetHashCode() => Value.GetHashCode();

    public override bool Equals(object obj) { throw new NotSupportedException(); }

    public static bool operator ==(IntWrapper left, IntWrapper right) { throw new NotSupportedException(); }

    public static bool operator !=(IntWrapper left, IntWrapper right) { throw new NotSupportedException(); }
}

internal static partial class Program
{
    private static void Main()
    {
        var d = new Dictionary<IntWrapper, string>
        {
            { new IntWrapper(42), "Hello" },
            { new IntWrapper(1729), "World" },
        };

        var s = d[new IntWrapper(1729)];
        Console.WriteLine(s);
    }
}

Заодно убедишься, что `bool Equals(object obj) { throw new NotSupportedException(); }` тоже не вызывается.

V>Т.е., следующий твой шаг в рассуждениях от T к ISomeInterface<T> был слишком очевидным на тот момент... Ан нет, до тебя даже такой толстый намёк не дошёл. :xz:


Всем очевидно, что приводить аргументы в защиту твоей позиции — это твоя забота, а не оппонента. Если уж предугадываешь «слишком очевидные» шаги — продолжай это делать. Расписывай дальше, какими хаками обмазываться в плюсах и что к чему кастить, если в функцию передаётся не `T *`, а `std::vector<T>`, `std::function<T()>`, `std::function<void(T)>` и так далее.

V>Ты ведь вызвался оспорить вот это:

V>

V>Собсно, вообще таких алгоритмов мало, которые можно выразить в дотнете для value и ref-типов в генериках и они будут корректно работать в обоих случаях.

V>Ну как, получилось? :facepalm:

Конечно, пример с `IEquotable<T>` это наглядно показывает. В этом примере http://ideone.com/9tlRqT сделай Foo классом, а не структурой — всё будет «корректно работать в обоих случаях».

V>Разве ты еще не увидел, что твой пример был неудачный?

V>Что надо было дать некий struct ValueTypeComparer<T>

Ты просто не понял примера. Он был не про компарер и его использование. А про использование внутри него `IEquatable<T>`: не через `...some-method...(IEquatable<T> x, IEquatable<T> y)`, а через `...some-method...(T x, T y) ... where T : IEquatable<T>`:
public interface IEquatable<T>
{
    bool Equals(T other);
}

internal ...some-class...<T> ... where T : IEquatable<T>
{
    public override bool ...some-method...(T x, T y)
    {
        if (x != null)
        {
            if (y != null) return x.Equals(y);
            return false;
        }
        if (y != null) return false;
        return true;
    }

    ///...
}


V>Что даже указанный тобой "типизированный" вызов x.Equals(y) происходит внутри генерик-метода, реализующего интерфейс? (что ты скромно делаешь вид, что не замечаешь или подзабыл, угу)


В примере это вообще не важно, вызывающий «генерик-метод» может ничего не реализовывать, а быть сам по себе. Тут важно, что некий алгоритм выражается не напрямую через `IEquatable<T>`, а выражается в терминах `T : IEquatable<T>`, что позволяет передавать ему структуры без боксинга.

V>Ну и возвращаясь к нашим баранам. Вот, если быть честным с самим собой (забыть на минуту о запале форумного боя), ты что, ДЕЙСТВИТЕЛЬНО не согласен с процитированным (последнее на жёлтеньком)?


Да, расскажи, что помешает в этом примере http://ideone.com/9tlRqT сделать `Foo` не структурой а классом?

V>А то ж, если будешь продолжать упираться, то уже мне придется шутить о соответствии хотя бы джуниору, только, в отличие от, с полным основанием-то. ))


Твоё утверждение «Никак он не вызывается. x.Equals(y) — это метод базового Object» наглядно свидетельствует о том, что ты совершенно не понимаешь происходящего. Вопрос вполне можно рекомендовать к включению в собеседование на должность джуниора, чтобы сразу отсеевать тех, кто не обладает минимальной компетенцией.
Глаза у меня добрые, но рубашка — смирительная!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.