2015-12-08 1 views
2

Компилятор VS2015 C# испускает атрибуты [Serializable, CompilerGenerated] для всех автогенерируемых вспомогательных классов для запросов LINQ. Предыдущие версии Visual Studio использовались для испускания только атрибутов [CompilerGenerated] для таких классов.Отключить автоматическое генерирование атрибута [Serializable] с помощью VS2015 C# compiler

Есть ли способ отключить автогенерацию атрибута [Serializable] в VS2015? Причина в том, что наш обфускатор отказывается переименовывать классы, обозначенные как [Serializable], хотя в нашем случае он на 100% безопасен, потому что мы не используем сериализацию.

Вот пример автоматического кода, сгенерированного старых компиляторов:

[CompilerGenerated] 
private sealed class <>c 
{ 
    public static readonly Program.<>c <>9 = new Program.<>c(); 
    // ... more stuff here 
} 

Вот что излучает VS2015:

[Serializable, CompilerGenerated] 
private sealed class <>c 
{ 
    public static readonly Program.<>c <>9 = new Program.<>c(); 
    // ... more stuff here 
} 

Я хочу, чтобы компилятор не создавать этот атрибут [Serializable]. Является ли это возможным?

ответ

0

я в конечном итоге написание простого инструмента dnlib основы, что анализирует скомпилированную сборку и изменяет свойство Serialized каждого класса с атрибутом [CompilerGenerated] равным false. Кажется, он работает достаточно хорошо для моих нужд.

1

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

Итак, Roslyn - это компилятор, который генерирует код (это компилятор по умолчанию в VS2015), и он является открытым исходным кодом (см. here). LabdaRewriter.cs (here) содержит логику, которая переписывает лямбда в класс и делает все магию. В методе GetStaticFrame есть эта строка:

_lazyStaticLambdaFrame = new LambdaFrame(_topLevelMethod, scopeSyntaxOpt: null, methodId: methodId, closureId: closureId); 

Теперь LamdaFrame это класс, который представляет сгенерированный класс (см here) (в вашем случае <>c который получает SerializableAttribute).

Помните часть scopeSyntaxOpt: null от параметра конструктора!

Вот конструктор:

internal LambdaFrame(MethodSymbol topLevelMethod, CSharpSyntaxNode scopeSyntaxOpt, DebugId methodId, DebugId closureId) 
      : base(MakeName(scopeSyntaxOpt, methodId, closureId), topLevelMethod) 
{ 
      _topLevelMethod = topLevelMethod; 
      _constructor = new LambdaFrameConstructor(this); 
      this.ClosureOrdinal = closureId.Ordinal; 
     // static lambdas technically have the class scope so the scope syntax is null 
     if (scopeSyntaxOpt == null) 
     { 
      _staticConstructor = new SynthesizedStaticConstructor(this); 
      var cacheVariableName = GeneratedNames.MakeCachedFrameInstanceFieldName(); 
      _singletonCache = new SynthesizedLambdaCacheFieldSymbol(this, this, cacheVariableName, topLevelMethod, isReadOnly: true, isStatic: true); 
     } 
     ... 
} 

И есть одно свойство называется IsSerializable:

// display classes for static lambdas do not have any data and can be serialized. 
    internal override bool IsSerializable 
    { 
     get { return (object)_singletonCache != null; } 
    } 

Как вы видите, в конструкторе это _ singletonCache не в принципе никогда не нуль, когда экземпляр создается в метод GetStaticFrame (я думаю, что это тот случай, когда вы не захватываете значения извне в выражении LINQ (FIXME)), поэтому возвращает true, и я думаю, что на основе этого свойства сгенерированный класс get является Serializ ableAttribute.

Так что я думаю, что на данный момент это жестко, и вы не можете изменить это, если вы не трогать исходный код Roslyn и улучшить это ....

+0

Благодарим вас за это исследование, я подозревал что-то в этом роде. Я думаю, что проще всего просто написать инструмент для изменения скомпилированной сборки. –

+1

Да, это звучит как хороший обходной путь для вашего дела. Btw. Я бы предложил добавить тег Roslyn на ваш вопрос ... Люди, которые гораздо больше знакомы с кодовым основанием, а затем меня, иногда болтаются здесь ... может быть, у них есть лучшее решение. Я также опубликовал редактирование с этим, но оно было отклонено ... – gregkalapos

Смежные вопросы