Я был поклонником обучающего 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.
Это похоже на то, как будто Леви намеренно пытается быть неясным в том, что он говорит. Я не слушал подкаст, но, судя по умляутам, считаю, что английский - не его родной язык.
Некоторые объекты, которые вы используете в .NET, действительно являются оболочками для COM-объектов. А создаваемый вами .NET-объект делает многое из того, что должен делать COM, и даже больше, без неприятных неприятностей со стороны COM. Я не думаю, что утверждение «это все COM внизу» является точным или ясным.
Я бы хотел, чтобы интервью было с Джеффом Рихтером. ; -)
.NET / CLR начал жизнь как лучший COM (Глава 1 в этой книге )
Но не основывается на COM, поскольку он устранил многие проблемные области COM. (Управление памятью на основе подсчета ссылок, небезопасные указатели, зависимости реестра ...)
Но он может использовать объекты COM и может заключать объекты .NET в оболочку COM. Но объект .NET не является COM-объектом.
Интерфейс хостинга для реализации .NET в Windows основан на нескольких интерфейсах COM.
Ответ Дэйва Маркл напомнил мне кое-что, что Джефф Рихтер сказал в 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-объектом») и сборках приложений, так что это может быть причиной путаницы.
Я думаю, он говорит о базовой реализации CLR. Насколько я понимаю, он не говорит о взаимодействии миров COM и .NET. Он просто говорит нам, что они использовали C ++ и COM в реализации среды выполнения.
Я исходил из предположения, что вполне возможно писать сборки C ++, совместимые с .NET CLI, которые не имеют абсолютно ничего общего с COM / ATL / ActiveX?
Да, вы можете использовать C ++ / CLI для создания только сборок MSIL, которые не имеют ничего общего с COM.
Я думаю из this и при наличии ICLRRuntimeHost
и различных других неуправляемых интерфейсов к внутренним компонентам CLR довольно очевидно, что .NET на самом деле построен поверх COM.
Я прослушал это, и мое впечатление было таким, что, хотя это и не было ясно на 100%, он говорил больше о среде выполнения .NET, чем о BCL.
Просто другой подход
^.{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.