Нашли или выдавили из себя код, который нельзя назвать нормальным,
на который без улыбки не взглянешь?
Не торопитесь его удалять или рефакторить, — запостите его на
говнокод.ру, посмеёмся вместе!
internal static object CreateDefaultEqualityComparer(Type type)
{
Debug.Assert(type != null && type is RuntimeType);
object result = null;
var runtimeType = (RuntimeType)type;
// Specialize for byte so Array.IndexOf is faster.
if (type == typeof(byte))
{
result = new ByteEqualityComparer();
}
// If T implements IEquatable<T> return a GenericEqualityComparer<T>
else if (typeof(IEquatable<>).MakeGenericType(type).IsAssignableFrom(type))
{
result = CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericEqualityComparer<int>), runtimeType);
}
// Nullable does not implement IEquatable<T?> directly because that would add an extra interface call per comparison.
// Instead, it relies on EqualityComparer<T?>.Default to specialize for nullables and do the lifted comparisons if T implements IEquatable.
else if (type.IsGenericType)
{
if (type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
result = TryCreateNullableEqualityComparer(runtimeType);
}
}
// The equality comparer for enums is specialized to avoid boxing.
else if (type.IsEnum)
{
result = TryCreateEnumEqualityComparer(runtimeType);
}
return result ?? CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(ObjectEqualityComparer<object>), runtimeType);
}
Код взят из CoreCLR mscorlib сырцов.
Внимание вопрос. Нахерна было писать эту обосгость когда данный метод легко делается генериком без какого либо вызова "невидимого" кода?
вот пример как все должно было быть
```
internal static object CreateDefaultEqualityComparer<T>()
{
// Specialize for byte so Array.IndexOf is faster.
if (typeof(T) == typeof(byte))
{
result = new ByteEqualityComparer();
}
// If T implements IEquatable<T> return a GenericEqualityComparer<T>
else if (typeof(IEquatable<T>).IsAssignableFrom( typeof(T)))
{
result new GenericEqualityComparer<T>();
}
// Nullable does not implement IEquatable<T?> directly because that would add an extra interface call per comparison.
// Instead, it relies on EqualityComparer<T?>.Default to specialize for nullables and do the lifted comparisons if T implements IEquatable.
else if (typeof(T).IsGenericType)
{
if (typeof(T).GetGenericTypeDefinition() == typeof(Nullable<>))
{
result = new NullableEqualityComparer<T>();
}
}
// The equality comparer for enums is specialized to avoid boxing.
else if (typeof(T).IsEnum)
{
result = TryCreateEnumEqualityComparer<T>();
}
return result ?? new ObjectEqualityComparer<T>();
}
```
internal static object CreateDefaultEqualityComparer<T>()
{
// Specialize for byte so Array.IndexOf is faster.
if (typeof(T) == typeof(byte))
{
result = new ByteEqualityComparer();
}
// If T implements IEquatable<T> return a GenericEqualityComparer<T>
else if (typeof(IEquatable<T>).IsAssignableFrom(typeof(T)))
{
result new GenericEqualityComparer<T>();
}
// Nullable does not implement IEquatable<T?> directly because that would add an extra interface call per comparison.
// Instead, it relies on EqualityComparer<T?>.Default to specialize for nullables and do the lifted comparisons if T implements IEquatable.
else if (typeof(T).IsGenericType)
{
if (typeof(T).GetGenericTypeDefinition() == typeof(Nullable<>))
{
result = new NullableEqualityComparer<T>();
}
}
// The equality comparer for enums is specialized to avoid boxing.
else if (typeof(T).IsEnum)
{
result = TryCreateEnumEqualityComparer<T>();
}
return result ?? new ObjectEqualityComparer<T>();
}
не шарпист, но с точки зрения кресто/нормального понимания, твой код будет уже компилером пропарсен, т.е. тип должен быть известен уже на стадии компиляции. оригинал - тип может быть известен в рантайме.
а если так, то тогда есть другой повод: в твоей реализации будет Н копий твоей функции, потому что на каждый уникальный тип будет личная копия инстанциирована.
в ихней реализации - будет только одна функция, в независимости от количества типов.
Ребята всё верно сделали, а ты чувак по осторожней с генерик методами. Там видел ребята выше писали что генерик метод будет один, это не верно. Тот кто читал рихтера, будут знать, что генерик тип при компиляции генерирует все допустимые типы этого объекта. Он ты накалякал, генерик тип на все типы в clr и твоей сборки:
`CreateDefaultEqualityComparer<T>`
Типов дохуя, как и перегрузок методов дохуя (отностительно clr, а не шарпа, потому что шарп интерпретируется и уже тогда компилируется, не забывай про сахарок).
Этот код писался не только для шарпа, заметь в имени CLR, а это значит что ещё и на плюсах этот код будет исполнятся.
вот тут покрасивше будет
Другими словами они сделали 100% привязку к runtime коду когда все и так прекрасно компилиться. А значит умысел у разработчиков не был добрый 🙂
а если так, то тогда есть другой повод: в твоей реализации будет Н копий твоей функции, потому что на каждый уникальный тип будет личная копия инстанциирована.
в ихней реализации - будет только одна функция, в независимости от количества типов.
next in new: a devastating bug was found in Unix! fork() system call doesn't work on Windows!!
нет
`CreateDefaultEqualityComparer<T>`
Типов дохуя, как и перегрузок методов дохуя (отностительно clr, а не шарпа, потому что шарп интерпретируется и уже тогда компилируется, не забывай про сахарок).
Этот код писался не только для шарпа, заметь в имени CLR, а это значит что ещё и на плюсах этот код будет исполнятся.