Подтвердить что ты не робот

Оптимизирует ли С# 4 пространство имен таким образом, что предыдущие версии С# этого не сделали?

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

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

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

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

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

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

Ответ 1

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

namespace N
{
    class C  {}
}

и psuedo-code:

class N.C {}

С# заставляет вас притворяться, что эта приятная фантастика - это реальность, но это просто фикция - с точки зрения системы типа CLR, конечно. С точки зрения компилятора С#, конечно, пространства имен являются "реальными". Они просто не соответствуют чему-либо в метаданных, кроме части имени типа.

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

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

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

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

Ответ 2

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

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

Ответ 3

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