C# - Тип Значения Равняется методу - почему компилятор использует отражение?

'Make the excel file that runs the software the active workbook
ThisWorkbook.Activate

'The first sheet used as a temporary place to hold the data 
ThisWorkbook.Worksheets(1).Cells.Copy

'Create a new Excel workbook
Dim NewCaseFile As Workbook
Dim strFileName As String

Set NewCaseFile = Workbooks.Add
With NewCaseFile
    Sheets(1).Select
    Cells(1, 1).Select
End With

ActiveSheet.Paste
16
задан Backwards_Dave 7 April 2016 в 23:35
поделиться

2 ответа

Ниже приведен декомпилированный метод ValueType.Equals из mscorlib:

public override bool Equals(object obj)
{
    if (obj == null)
    {
        return false;
    }
    RuntimeType type = (RuntimeType) base.GetType();
    RuntimeType type2 = (RuntimeType) obj.GetType();
    if (type2 != type)
    {
        return false;
    }
    object a = this;
    if (CanCompareBits(this))
    {
        return FastEqualsCheck(a, obj);
    }
    FieldInfo[] fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
    for (int i = 0; i < fields.Length; i++)
    {
        object obj3 = ((RtFieldInfo) fields[i]).InternalGetValue(a, false);
        object obj4 = ((RtFieldInfo) fields[i]).InternalGetValue(obj, false);
        if (obj3 == null)
        {
            if (obj4 != null)
            {
                return false;
            }
        }
        else if (!obj3.Equals(obj4))
        {
            return false;
        }
    }
    return true;
}

По возможности будет выполнено побитовое сравнение (обратите внимание на CanCompareBits и FastEqualsCheck, оба из которых определены как InternalCall . Предположительно, JIT внедрит сюда соответствующий код. Что касается того, почему он такой медленный, я не могу вам сказать.

10
ответ дан 30 November 2019 в 21:54
поделиться

Он не использует отражение , когда ему не нужно . Он просто сравнивает значения бит за битом в случае struct , если это возможно. Однако, если какой-либо из членов struct (или членов членов, любых потомков) переопределяет object.Equals и предоставляет свою собственную реализацию, очевидно, он не может полагаться на бит- побитовое сравнение для вычисления возвращаемого значения.

Причина этого заключается в том, что параметр Equals имеет тип объект , а типы значений должны быть упакованы в коробки, чтобы их можно было рассматривать как объект . Упаковка включает в себя выделение памяти в куче и копирование памяти типа значения в это место.

Вы можете вручную предоставить перегрузку для метода Equals , который принимает вашу собственную структуру в качестве параметра для предотвращения упаковки:

public bool Equals(MyStruct obj) {
     return obj.i == i;
}
10
ответ дан 30 November 2019 в 21:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: