1. C# / Говнокод #23243

    0

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    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>();
    }
    ```

    Запостил: ASD_77, 07 Августа 2017

    Комментарии (10) RSS

    • 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>();
              }


      вот тут покрасивше будет
      Ответить
      • не шарпист, но с точки зрения кресто/нормального понимания, твой код будет уже компилером пропарсен, т.е. тип должен быть известен уже на стадии компиляции. оригинал - тип может быть известен в рантайме.
        Ответить
        • я о том же и говорю что там нахрен не нужен код для runtime потому что код вызывается из generic-a т.е. параметер метода не есть рантайм переменная.

          Другими словами они сделали 100% привязку к runtime коду когда все и так прекрасно компилиться. А значит умысел у разработчиков не был добрый :)
          Ответить
          • > потому что код вызывается из generic-a

            а если так, то тогда есть другой повод: в твоей реализации будет Н копий твоей функции, потому что на каждый уникальный тип будет личная копия инстанциирована.

            в ихней реализации - будет только одна функция, в независимости от количества типов.
            Ответить
            • В шарпе и так она одна будет. Это только плюсы на каждый тип код копируют.
              Ответить
              • может авторы CoreCLR (ака авторы цлр и дотнета) знают нечто что обычные пользователи шарпов не знют? ну это чисто так - догадка.
                Ответить
                • Лично я вижу это как целенаправленное ухудшение портабильности кода, т.е. искустеванная привязка кода к VM
                  Ответить
                  • ты может "CoreCLR" в имени проекта не заметил?

                    next in new: a devastating bug was found in Unix! fork() system call doesn't work on Windows!!
                    Ответить
              • > только
                нет
                Ответить
    • Ребята всё верно сделали, а ты чувак по осторожней с генерик методами. Там видел ребята выше писали что генерик метод будет один, это не верно. Тот кто читал рихтера, будут знать, что генерик тип при компиляции генерирует все допустимые типы этого объекта. Он ты накалякал, генерик тип на все типы в clr и твоей сборки:
      `CreateDefaultEqualityComparer<T>`
      Типов дохуя, как и перегрузок методов дохуя (отностительно clr, а не шарпа, потому что шарп интерпретируется и уже тогда компилируется, не забывай про сахарок).

      Этот код писался не только для шарпа, заметь в имени CLR, а это значит что ещё и на плюсах этот код будет исполнятся.
      Ответить

    Добавить комментарий