Оптимизирует ли C # 4 пространства имен таким же образом, как это делали предыдущие версии C #? - PullRequest
44 голосов
/ 06 марта 2012

Этот вопрос ради интереса. Я работаю со сторонней библиотекой и наткнулся на следующую документацию по классу CMS.Security.Dummy:

НЕ УДАЛЯТЬ ЭТОТ КЛАСС - Этот класс не позволяет компилятору удаление всего пространства имен в .NET 4.0.

Кто-нибудь знает или кто-нибудь может предположить, почему .NET 4 отбросил бы пространство имен, если бы фиктивный класс был удален?

Поскольку .NET 4 явно указан в комментарии к исходному коду, я предполагаю, что предыдущие версии C # демонстрируют поведение, которое не требует этого фиктивного класса. Это чисто умозрительно, хотя.

Снимок экрана

documentation

Декомпилированный исходный код

#region Assembly CMS.SettingsProvider.dll, v4.0.30319
// ...\solution\wwwroot\Bin\CMS.SettingsProvider.dll
#endregion

using System;

namespace CMS.Security
{
    // Summary:
    //     DO NOT DELETE THIS CLASS - This class prevents the compiler from dropping
    //     entire namespace under .NET 4.0.
    public class Dummy
    {
        // Summary:
        //     DO NOT DELETE THIS CLASS - This class prevents the compiler from dropping
        //     entire namespace under .NET 4.0.
        public Dummy();
    }
}

Ответы [ 3 ]

90 голосов
/ 06 марта 2012

Мало ценится тот факт, что с точки зрения базовой системы типов CLR не существует такого понятия, как «пространство имен». Скорее, это просто соглашение , что мы говорим, что тип, который содержит точки в своем имени, является "членом пространства имен". Логически нет никакой разницы между юридическим кодом:

namespace N
{
    class C  {}
}

и псевдо-код:

class N.C {}

C # заставляет вас притворяться, что эта приятная выдумка - реальность, но это всего лишь выдумка - с точки зрения системы типов CLR, конечно. С точки зрения компилятора C #, конечно, пространства имен являются «реальными». Они просто не соответствуют ничему в метаданных, кроме части имени типа.

Вкратце: если вы делаете сборку с «пустым» пространством имен, то «пространство имен» вообще не существует в скомпилированном двоичном файле. «Пространство имен» появляется только в том случае, если в библиотеке есть тип, в имени которого есть точки.

Теперь, почему вы заботитесь о том, чтобы "пустое" пространство имен присутствовало в двоичной форме, я понятия не имею.

Я предполагаю, что предыдущие версии C # демонстрируют поведение, которое не требует этого фиктивного класса

Неа. Каждая версия C # начиная с 1.0 выбрасывает пустые пространства имен.

23 голосов
/ 06 марта 2012

Учитывая, что пространство имен не содержит каких-либо членов (без этого класса), я не уверен, что даже концепция *1002* пространства имен в этот момент существует ... и я не ожидаю, что он будетв любом случае полезно.

Я только что попытался воспроизвести это с помощью компилятора C # 2, и я не вижу никаких следов пустого пространства имен в IL.

7 голосов
/ 06 марта 2012

Единственная полу-связанная проблема, о которой я могу подумать, это то, что при компиляции проекта в msbuild косвенные ссылки не всегда копируются в каталог bin текущего приложения. Если библиотека B косвенно ссылается на библиотеку A, а библиотека C ссылается только на B, выходные данные библиотеки A не обязательно будут скопированы в папку bin при компиляции библиотеки C. В прошлом я использовал ссылку на нулевое поле в классе, чтобы гарантировать, что зависимость является явной, а выходные данные развернуты правильно. Может быть, оригинальные разработчики испытали нечто подобное, и это было их решением?

...