Roslyn C#6? Компиляция оператора выглядит беспорядочно в универсальных типах

Давайте рассмотрим следующее определение класса:

public class MyClass<T>
{
    public T t;
    public bool? c1(T obj) => obj?.Equals(null);
    public bool? c2() => t?.Equals(null);
}

В конце концов, некоторые заметки:

  • MyClass<T> не накладывать никаких ограничений на T типа - так, T может быть class или struct;
  • c2() == c1(t) ДОЛЖЕН БЫТЬ всегда верным.
  • Я использую сайт http://tryroslyn.azurewebsites.net/ чтобы скомпилировать некоторые фрагменты кода и посмотреть, что выделяет Рослин.

Теперь давайте проанализируем, как компилирует Roslyn MyClass<T>:

1.) c1(T) дело:

Как и ожидалось, после проверки сгенерированного кода компилятором Roslyn, мы можем увидеть следующее:

public bool? c1(T obj)
{
    return obj != null ? new bool?(obj.Equals(null)) : null;
}

2.) c2() дело:

То, что я ожидал, было таким же кодом, как c1(T). Но то, что я вижу, это:

public unsafe bool? c2()
{
    T* arg_33_0 = ref this.t;
    T t = default(T);
    bool? arg_43_0;
    if (t == null)
    {
        t = this.t;
        arg_33_0 = ref t;
        if (t == null)
        {
            arg_43_0 = null;
            return arg_43_0;
        }
    }
    arg_43_0 = new bool?(arg_33_0.Equals(null));
    return arg_43_0;
}

ВАУ, почему выдается весь этот ненужный код? В режиме компиляции релиза мы видим, что код C1 имеет размер кода 39 байт, а метод C2 - 68 байтов. Это то, что можно оптимизировать?

1 ответ

Решение

c1 Код CIL будет неправильным для c2 дело.

в c1 версия, Equals вызывается на копию obj, в c2 версия, особое внимание должно быть уделено, чтобы позвонить Equals на t, а не копия t, Это потому что T может быть типом значения, который был переопределен Equals изменить свои собственные данные экземпляра. Так как ты звонишь Equals на tмодификация должна быть видна в t,

Оптимизация возможна для c1 только потому, что ни у кого нет возможности проверить obj после того, как метод вернулся, не имеет значения, является ли он obj или копия obj это потенциально может быть изменено.

Другие вопросы по тегам