Как определить, является ли Type инициализатором статического массива? - PullRequest
1 голос
/ 15 октября 2011

Начну с того, что я отрабатываю предположение, что инициализаторы статических массивов превращаются компилятором в частные вложенные классы, обычно с именами, такими как __StaticArrayInitTypeSize=12. Насколько я понимаю, прочитав эту чрезвычайно информативную статью , эти частные классы являются типами значений и не помечены CompilerGeneratedAttribute классом.

Я работаю над проектом, который должен обрабатывать определенные типы и игнорировать другие.

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

Я вытягиваю эти классы с Linq, вот так:

var typesToProcess = allTypes.Where(type => !type.IsEnum &&
                                            !type.IsArray &&
                                            !type.IsSubclassOf(typeof(Delegate)));

Я совершенно уверен, что свойство IsArray не то, что я думаю. В любом случае, сгенерированный класс инициализатора статического массива по-прежнему отображается в typesToProcess Enumerable.

Кто-нибудь еще имел дело с этим? Как я могу различить разницу между пользовательской структурой и классом инициализатора статического массива? Я могу взломать его, сравнив имя типа с __StaticArrayInitTypeSize, но есть ли более чистое решение?

1 Ответ

1 голос
/ 15 октября 2011

Что ж, только что попробовав это сам с компилятором C # 4, я получил внутренний класс с именем <PrivateImplementationDetails>{D1E23401-19BC-4B4E-8CC5-2C6DDEE7B97C}, содержащий частную вложенную struct с именем __StaticArrayInitTypeSize=12.

Класс содержит внутреннее статическое поле типа структуры с именем $$method0x6000001-1. Само поле было украшено CompilerGeneratedAttribute.

Проблема в том, что все зависит от реализации. Он может измениться в будущих выпусках или может отличаться от более ранних выпусков.

Любое имя члена, содержащее <, > или =, является «невыразимым» именем, которое будет сгенерировано компилятором, так что вы можете рассматривать его как неявное CompilerGenerated, если в этом есть какая-то польза. (Существует любое количество других использований для таких сгенерированных типов.)

...