Здравствуйте, 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» наглядно свидетельствует о том, что
ты совершенно не понимаешь происходящего. Вопрос вполне можно рекомендовать к включению в собеседование на должность джуниора, чтобы сразу отсеевать тех, кто не обладает минимальной компетенцией.