2016-05-11 52 views
5

Dato il programma di console di seguito:Perché Action.Method.IsStatic diversa tra Visual Studio 2013 e il 2015 per alcune espressioni lambda

class Program 
{ 
    private static string _value; 
    static void Main(string[] args) 
    { 
     var t = new Action(() => _value = "foo"); 
     Console.Out.WriteLine("t.Method.IsStatic: {0}", t.Method.IsStatic); 
    } 
} 

Quando compilato contro .Net 4.5.2 utilizzando VS 2013, stamperà

t.Method.IsStatic: true 

Quando compilato contro .Net 4.5.2 utilizzando VS 2015, verrà stampata

t.Method.IsStatic: false 

Da 01.237.280,954 miladomanda, in qualche modo capisco cosa sta succedendo, ma sono confuso perché c'è un cambiamento nel comportamento tra le versioni di VS. Da quanto ho capito, l'output del 2013 è corretto.

risposta

4

Verificare la risposta al seguente link: Delegate caching behavior changes in Roslyn

Fondamentalmente cosa è cambiato e cito @Yuzal dalla risposta collegata:

comportamento

"Delegato caching è stato cambiato a Roslyn In precedenza, come . dichiarato, qualsiasi espressione lambda che non ha catturato le variabili è stata compilata in un metodo statico nel sito di chiamata.Roslyn ha modificato questo comportamento . Ora, qualsiasi lambda, che acquisisce le variabili o no, è trasformato in un di classe splay: "

E per classe di visualizzazione intendeva una classe privata sigillata generata all'interno della quale incapsula il metodo di istanza invocato dal delegato dell'azione.

Perché è stata apportata la modifica? Citando @ Kevin Pilch-Bisson (un membro del C# squadra IDE):

Il motivo è più veloce è perché invoca delegati sono ottimizzati per metodi di istanza e hanno spazio sullo stack per loro. Per chiamare un metodo statico devono spostare i parametri.

Quindi, in sostanza, il commento è autoesplicativo. La differenza di comportamento che vedi nell'esempio sopra è perché ha notato che se il metodo Action ha invocato metodi di istanza è più veloce del richiamo di metodi statici, indipendentemente dal fatto che lambda acquisisca o meno le variabili.

+0

Sì, questo è il problema. Sfortunatamente, questo causa strani problemi se usi WeakReferences. – MattS

+0

@MattS hmmm, puoi approfondire? –

+0

@MattS Quando ci si basa su comportamenti privi di documenti, è necessario prevedere problemi. – svick

0

Apparirà dal this che il comportamento è cambiato tra il compilatore 2013 e Rosyln. Molto noioso.