Оптимизирует ли С# 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();
}
}
Ответы
Ответ 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. В прошлом я использовал ссылку нулевого поля для класса, чтобы убедиться, что зависимость явно, а выход развернут правильно. Возможно, оригинальные разработчики испытали нечто похожее, и это было их решение?