Вопрос ради интереса. Я работаю со сторонней библиотекой и наткнулся на следующую документацию по классу 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();
    }
}
45
John K 6 Мар 2012 в 01:40

3 ответа

Лучший ответ

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

namespace N
{
    class C  {}
}

И псевдокод:

class N.C {}

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

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

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

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

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

90
Eric Lippert 5 Мар 2012 в 22:22

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

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

23
Jon Skeet 5 Мар 2012 в 21:45

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

7
Chris 5 Мар 2012 в 21:50