Является.NET “всем COM внизу”?

Я был поклонником обучающего Juval Lowy и руководство в разработке.NET в течение многих лет. Он также записал одну из моих любимых книг: Программирование Компонентов.NET.

Однако на недавнем подкасте DotNet-Rocks (Jan 2010) в обсуждении WCF/COM и.NET, он сделал некоторые комментарии, которые значительно удивили меня:

Juval Löwy:..... в.NET, о чудо, каждый класс здесь является COM-объектом. Мы знаем это. На самом деле это намного больше, чем COM, потому что у нас есть мерзавец, компилирующий, у нас есть сборка "мусора", у нас есть Стопка безопасности....

Carl Franklin: Ну, необходимо разъяснить это все же. Я имею в виду, каждый объект не является COM-объектом. Каждый объект имеет возможности, которые делает COM-объект, но Платформа.NET не является библиотекой COM.

Juval Löwy: Нет, нет. В первую очередь.NET на самом деле создается сверху COM. Это - весь COM внизу.

Затем после того, как Carl Franklin просит разъяснение по поводу этого комментария:

Carl Franklin: Да, я получаю это. Моим вопросом была.NET, основан на COM?

Juval Löwy: Конечно, все это COM внизу.

Carl Franklin: Нет. Я знаю, что это переплетено, и требуется, но когда Вы новый.NET возражает, что Вы не создаете COM-объект.

Juval Löwy: Вы создаете объект.NET, но все, что я говорю, - то, что.NET создается внизу. Это - весь C++ и COM.

Carl Franklin: Это - C++, но Вы не регистрируете COM-объект через COM-интерфейс. Это не все это, если Вы конкретно не делаете это.

Juval Löwy: Но часть материала использует COM внизу, но это не относится к делу. Забудьте о том, как это сделано.

Как Вы читаете эти комментарии?

В то время как я понимаю (и подтвердили), что некоторые Системные блоки записаны в неуправляемом C++, это также допустимо, чтобы сказать, что они - "весь COM внизу"?

Я находился под предположением, совершенно возможно записать.NET CLI совместимые блоки C++, которые абсолютно не имеют никакого отношения к COM / ATL / ActiveX?

Вот расшифровка стенограммы PDF для рассматриваемого подкаста. Посмотрите Страницу 7.

34
задан Ash 17 February 2010 в 14:10
поделиться

7 ответов

Это похоже на то, как будто Леви намеренно пытается быть неясным в том, что он говорит. Я не слушал подкаст, но, судя по умляутам, считаю, что английский - не его родной язык.

Некоторые объекты, которые вы используете в .NET, действительно являются оболочками для COM-объектов. А создаваемый вами .NET-объект делает многое из того, что должен делать COM, и даже больше, без неприятных неприятностей со стороны COM. Я не думаю, что утверждение «это все COM внизу» является точным или ясным.

Я бы хотел, чтобы интервью было с Джеффом Рихтером. ; -)

7
ответ дан 27 November 2019 в 16:35
поделиться

.NET / CLR начал жизнь как лучший COM (Глава 1 в этой книге )

Но не основывается на COM, поскольку он устранил многие проблемные области COM. (Управление памятью на основе подсчета ссылок, небезопасные указатели, зависимости реестра ...)

Но он может использовать объекты COM и может заключать объекты .NET в оболочку COM. Но объект .NET не является COM-объектом.

Интерфейс хостинга для реализации .NET в Windows основан на нескольких интерфейсах COM.

6
ответ дан 27 November 2019 в 16:35
поделиться

Ответ Дэйва Маркл напомнил мне кое-что, что Джефф Рихтер сказал в CLR Via C # .

(Глава 21, Хостинг CLR и домены приложений)

.NET Framework работает поверх Microsoft Windows. Это означает, что .NET Framework должен быть построен с использованием технологий, с которыми Windows может взаимодействовать. Для начала, все файлы управляемого модуля и сборки должны использовать формат файла переносимого исполняемого файла Windows (PE) и быть либо файлом Windows EXE, либо динамическим -link библиотека (DLL).

При разработке CLR Microsoft реализовала его как COM-сервер , содержащийся внутри DLL; то есть Microsoft определила стандартный COM {{1} } для CLR и назначенные идентификаторы GUID этому интерфейсу и COM-серверу . Когда вы устанавливаете .NET Framework, COM-сервер, представляющий CLR, регистрируется в реестре Windows так же, как и любой другой COM-сервер. Если вы хотите дополнительную информацию по этой теме см. в заголовочном файле MSCorEE.h C ++ , который поставляется с .NET Framework SDK. Этот файл заголовка определяет идентификаторы GUID и определение неуправляемого интерфейса ICLRRuntimeHost.

Я предполагаю, что это довольно близко к объяснению комментариев Жувала.

Алекс ДеЛардж также подчеркивает в другом ответе, что существует разница между реализацией самой среды CLR и сборок библиотеки базовых классов.

Я определенно сосредоточился на сборках BCL (Жувал: «каждый clss здесь является COM-объектом») и сборках приложений, так что это может быть причиной путаницы.

17
ответ дан 27 November 2019 в 16:35
поделиться

Я думаю, он говорит о базовой реализации CLR. Насколько я понимаю, он не говорит о взаимодействии миров COM и .NET. Он просто говорит нам, что они использовали C ++ и COM в реализации среды выполнения.

Я исходил из предположения, что вполне возможно писать сборки C ++, совместимые с .NET CLI, которые не имеют абсолютно ничего общего с COM / ATL / ActiveX?

Да, вы можете использовать C ++ / CLI для создания только сборок MSIL, которые не имеют ничего общего с COM.

20
ответ дан 27 November 2019 в 16:35
поделиться

Я думаю из this и при наличии ICLRRuntimeHost и различных других неуправляемых интерфейсов к внутренним компонентам CLR довольно очевидно, что .NET на самом деле построен поверх COM.

3
ответ дан 27 November 2019 в 16:35
поделиться

Я прослушал это, и мое впечатление было таким, что, хотя это и не было ясно на 100%, он говорил больше о среде выполнения .NET, чем о BCL.

2
ответ дан 27 November 2019 в 16:35
поделиться

Просто другой подход

^.{0,2}([^w].*|.{4,})?$
-121--4648369-

Многие люди этого не знают, но .NET включает внутренний класс, называемый "PatternMatcher" (под пространством имен "System.IO").

Этот статический класс содержит только 1 метод: public static bool StrictMatchPattern (строковое выражение, имя строки)

Этот метод используется .net всякий раз, когда требуется сравнить файлы с подстановочными символами (FileSystemWatcher, GetFiles () и т.д.)

С помощью рефлектора я открыл здесь код. Он действительно не прошел через него, чтобы понять, как он работает, но он работает отлично,

Так что это код для всех, кто не хочет работать с неэффективным способом RegEx:

public static class PatternMatcher
{
    // Fields
    private const char ANSI_DOS_QM = '<';
    private const char ANSI_DOS_STAR = '>';
    private const char DOS_DOT = '"';
    private const int MATCHES_ARRAY_SIZE = 16;

    // Methods
    public static bool StrictMatchPattern(string expression, string name)
    {
        expression = expression.ToLowerInvariant();
        name = name.ToLowerInvariant();
        int num9;
        char ch = '\0';
        char ch2 = '\0';
        int[] sourceArray = new int[16];
        int[] numArray2 = new int[16];
        bool flag = false;
        if (((name == null) || (name.Length == 0)) || ((expression == null) || (expression.Length == 0)))
        {
            return false;
        }
        if (expression.Equals("*") || expression.Equals("*.*"))
        {
            return true;
        }
        if ((expression[0] == '*') && (expression.IndexOf('*', 1) == -1))
        {
            int length = expression.Length - 1;
            if ((name.Length >= length) && (string.Compare(expression, 1, name, name.Length - length, length, StringComparison.OrdinalIgnoreCase) == 0))
            {
                return true;
            }
        }
        sourceArray[0] = 0;
        int num7 = 1;
        int num = 0;
        int num8 = expression.Length * 2;
        while (!flag)
        {
            int num3;
            if (num < name.Length)
            {
                ch = name[num];
                num3 = 1;
                num++;
            }
            else
            {
                flag = true;
                if (sourceArray[num7 - 1] == num8)
                {
                    break;
                }
            }
            int index = 0;
            int num5 = 0;
            int num6 = 0;
            while (index < num7)
            {
                int num2 = (sourceArray[index++] + 1) / 2;
                num3 = 0;
            Label_00F2:
                if (num2 != expression.Length)
                {
                    num2 += num3;
                    num9 = num2 * 2;
                    if (num2 == expression.Length)
                    {
                        numArray2[num5++] = num8;
                    }
                    else
                    {
                        ch2 = expression[num2];
                        num3 = 1;
                        if (num5 >= 14)
                        {
                            int num11 = numArray2.Length * 2;
                            int[] destinationArray = new int[num11];
                            Array.Copy(numArray2, destinationArray, numArray2.Length);
                            numArray2 = destinationArray;
                            destinationArray = new int[num11];
                            Array.Copy(sourceArray, destinationArray, sourceArray.Length);
                            sourceArray = destinationArray;
                        }
                        if (ch2 == '*')
                        {
                            numArray2[num5++] = num9;
                            numArray2[num5++] = num9 + 1;
                            goto Label_00F2;
                        }
                        if (ch2 == '>')
                        {
                            bool flag2 = false;
                            if (!flag && (ch == '.'))
                            {
                                int num13 = name.Length;
                                for (int i = num; i < num13; i++)
                                {
                                    char ch3 = name[i];
                                    num3 = 1;
                                    if (ch3 == '.')
                                    {
                                        flag2 = true;
                                        break;
                                    }
                                }
                            }
                            if ((flag || (ch != '.')) || flag2)
                            {
                                numArray2[num5++] = num9;
                                numArray2[num5++] = num9 + 1;
                            }
                            else
                            {
                                numArray2[num5++] = num9 + 1;
                            }
                            goto Label_00F2;
                        }
                        num9 += num3 * 2;
                        switch (ch2)
                        {
                            case '<':
                                if (flag || (ch == '.'))
                                {
                                    goto Label_00F2;
                                }
                                numArray2[num5++] = num9;
                                goto Label_028D;

                            case '"':
                                if (flag)
                                {
                                    goto Label_00F2;
                                }
                                if (ch == '.')
                                {
                                    numArray2[num5++] = num9;
                                    goto Label_028D;
                                }
                                break;
                        }
                        if (!flag)
                        {
                            if (ch2 == '?')
                            {
                                numArray2[num5++] = num9;
                            }
                            else if (ch2 == ch)
                            {
                                numArray2[num5++] = num9;
                            }
                        }
                    }
                }
            Label_028D:
                if ((index < num7) && (num6 < num5))
                {
                    while (num6 < num5)
                    {
                        int num14 = sourceArray.Length;
                        while ((index < num14) && (sourceArray[index] < numArray2[num6]))
                        {
                            index++;
                        }
                        num6++;
                    }
                }
            }
            if (num5 == 0)
            {
                return false;
            }
            int[] numArray4 = sourceArray;
            sourceArray = numArray2;
            numArray2 = numArray4;
            num7 = num5;
        }
        num9 = sourceArray[num7 - 1];
        return (num9 == num8);
    }
}
-121--1469898-

Я считаю, что Лёви специально говорит о Windows реализации .NET. Поскольку COM является такой огромной частью инфраструктуры Windows, это не странно, что .NET использует это. Однако .NET доступен также на платформах , отличных от Windows , поэтому я не вижу, как COM является основой для .NET.

16
ответ дан 27 November 2019 в 16:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: