Учитывая следующие 3 класса файлов:
file class MyClass
{
}
file class MyClass2
{
}
file class MyClass3
{
public int MyMember { get; init; }
}
После декомпиляции этого кода C# классы файлов теперь выглядят так:
internal class <Class1>FFEAE62924BA736A3C9E8DE39EA3099D227B65B02C0A6BC7FECCB5FF0D5B9D8B3__MyClass
{
}
internal class <Class1>FFEAE62924BA736A3C9E8DE39EA3099D227B65B02C0A6BC7FECCB5FF0D5B9D8B3__MyClass2
{
}
internal class <Class1>FFEAE62924BA736A3C9E8DE39EA3099D227B65B02C0A6BC7FECCB5FF0D5B9D8B3__MyClass3
{
public int MyMember { get; init; }
}
Я понимаю, что <Class1> — это имя исходного файла, в котором был определен класс файла, а MyClass... — это имя класса файла.
Чего я не понимаю, так это очень длинного, казалось бы, идентификатора между ними:
FFEAE62924BA736A3C9E8DE39EA3099D227B65B02C0A6BC7FECCB5FF0D5B9D8B3
Насколько я понимаю, оно варьируется в зависимости от имени исходного файла, что удивительно, когда текст между двумя угловыми скобками <Class1>, кажется, уже играет роль.
Как компилятор C# создает этот идентификатор? Я не смог найти никакой информации об этом в Интернете. Кажется, без документов.
@ Flydog57 Flydog57 Сначала я бы согласился, хотя этот вопрос задан не только из любопытства, но и потому, что он действительно нужен мне для моего проекта, и что наличие одного и того же точного идентификатора было бы полезно вместо традиционного способа генерации случайного числа или нить. В конце концов, я узнал, как генерируется этот идентификатор, несколько минут назад.





Я решил покопаться дальше в исходном коде Roslyn. С помощью временного автоматизированного инструмента для поиска каждого исходного файла C#, содержащего FileLocalType, оказалось около 12 исходных файлов C#.
В конце концов я приехал сюда. Код, который генерирует этот идентификатор:
internal static string MakeFileTypeMetadataNamePrefix(string filePath, ImmutableArray<byte> checksumOpt)
{
var pooledBuilder = PooledStringBuilder.GetInstance();
var sb = pooledBuilder.Builder;
sb.Append('<');
AppendFileName(filePath, sb);
sb.Append('>');
sb.Append((char)GeneratedNameKind.FileType);
if (checksumOpt.IsDefault)
{
// Note: this is an error condition.
// This is only included for clarity for users inspecting the value of 'MetadataName'.
sb.Append("<no checksum>");
}
else
{
foreach (var b in checksumOpt)
{
sb.AppendFormat("{0:X2}", b);
}
}
sb.Append("__");
return pooledBuilder.ToStringAndFree();
}
Посмотрев дальше, я могу сделать вывод, что загадочный идентификатор здесь — это полный (абсолютный) путь к исходному файлу, в котором определен класс файла, хешированный с использованием алгоритма хеширования SHA256 (иногда, очевидно, SHA1, но по умолчанию SHA256). И да, мне действительно нужен этот алгоритм вместо того, чтобы просто генерировать случайное целое число и затем преобразовывать результат в строку, что было бы традиционным способом сделать это, но это отвечает на вопрос.
И по какой-то причине к этим идентификаторам добавляется буква «F» из-за этой строки кода в том же методе MakeFileTypeMetadataNamePrefix:
sb.Append('>');
/*HERE -->*/sb.Append((char)GeneratedNameKind.FileType);
if (checksumOpt.IsDefault)
В моем случае вот эта длинная хешированная строка:
FFEAE62924BA736A3C9E8DE39EA3099D227B65B02C0A6BC7FECCB5FF0D5B9D8B3
является результатом хеширования этой строки с использованием алгоритма SHA256, к результату которого добавляется буква «F»:
C:\Users\User\source\repos\TemporaryAppRepository\FileClassTest\Class1.cs
придирка: он не «зашифрован», он хэширован.
Предупреждаем: не полагайтесь на недокументированное поведение. Microsoft может изменить его в любое время.
Наличие угловых скобок в имени класса делает имя класса незаконным в C# (но все же допустимым в CLR). Это делает возможным конфликт имен с другими именами в вашем коде (помните, что это делает компилятор — он может нарушить все правила, которые захочет). Генерация GUID или случайного числа с большим количеством энтропии (и преобразование результата в строку) — традиционный способ получить уникальное имя. Имя для вас не имеет значения, и вам не следует полагаться на такое поведение; беспокойтесь о задокументированном поведении