рд░реЛрдЬрд▓рд┐рди рдХреНрдпрд╛ рд╣реИ?
рд░реЛрдЬрд▓рд┐рди рдорд╛рдЗрдХреНрд░реЛрд╕реЙрдлреНрдЯ рдХреЗ C # рдФрд░ VisualBasic .NET рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдУрдкрди рд╕реЛрд░реНрд╕ рдХрдВрдкрд╛рдЗрд▓рд░ рдФрд░ рдХреЛрдб рдПрдирд╛рд▓рд┐рд╕рд┐рд╕ рдПрдкреАрдЖрдИ рдХрд╛ рдПрдХ рд╕реЗрдЯ рд╣реИред
рд░реЛрд╕рд▓рд┐рди рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдХреЛрдб рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдиреЗ, рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдЦреЛрдЬрдиреЗ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдЙрдкрдХрд░рдг рд╣реИред
рд╕рд┐рдВрдЯреЗрдХреНрд╕ рдЯреНрд░реА рдФрд░ рд╕рд┐рдореЗрдВрдЯрд┐рдХ рдореЙрдбрд▓
рдХреЛрдб рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдХреЗ рдкреЗрдбрд╝ рдФрд░ рдЕрд░реНрде рдореЙрдбрд▓ рдХреА рд╕рдордЭ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдпреЗ рд╕реНрдереИрддрд┐рдХ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рджреЛ рдореБрдЦреНрдп рдШрдЯрдХ рд╣реИрдВред
рдПрдХ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рд╡реГрдХреНрд╖ рдПрдХ рддрддреНрд╡ рд╣реИ рдЬреЛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рдХреЛрдб рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдХреЛрдб рдХреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рджреМрд░рд╛рди, рдпрд╣ рдЗрд╕рдХреЗ рд╕рд╛рде рдЪрд▓рддрд╛ рд╣реИред
рдкреНрд░рддреНрдпреЗрдХ рдХреЛрдб рдореЗрдВ рдПрдХ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдЯреНрд░реА рд╣реЛрддрд╛ рд╣реИред рдЕрдЧрд▓реА рдХрдХреНрд╖рд╛ рдХреА рд╡рд╕реНрддреБ рдХреЗ рд▓рд┐рдП
class A { void Method() { } }
рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рд╡реГрдХреНрд╖ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:

рд╕рд┐рдВрдЯреИрдХреНрд╕рдЯреНрд░реА рдХрд╛ рдПрдХ рдкреНрд░рдХрд╛рд░ рдПрдХ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдЯреНрд░реА рд╣реИред рддреАрди рдореБрдЦреНрдп рддрддреНрд╡реЛрдВ рдХреЛ рдкреЗрдбрд╝ рдореЗрдВ рдкреНрд░рддрд┐рд╖реНрдард┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ: рд╕рд┐рдВрдЯреЗрдХреНрд╕рдиреЙрдбреНрд╕, рд╕рд┐рдВрдЯреИрдХреНрд╕рдЯреЙрдХреНрд╕реЗрдВрд╕, рд╕рд┐рдВрдЯреЗрдХреНрд╕рдЯреНрд░реАрд╡рд┐рдпрд╛ред
рд╕рд┐рдВрдЯреЗрдХреНрд╕рдиреЛрдбреНрд╕ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХрдВрд╕реНрдЯреНрд░рдХреНрд╢рди, рдЕрд░реНрдерд╛рддреН рдШреЛрд╖рдгрд╛рдУрдВ, рдСрдкрд░реЗрдЯрд░реЛрдВ, рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдЖрджрд┐ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВред C # рдореЗрдВ, рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХрдиреНрд╕реНрдЯреНрд░рдХреНрд╢рдВрд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рдПрдХ рд╡рд░реНрдЧ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддреЗ рд╣реИрдВ SyntaxNode
Syntaxtokens рддрддреНрд╡реЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИ рдЬреИрд╕реЗ: рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛, рдХреАрд╡рд░реНрдб, рд╡рд┐рд╢реЗрд╖ рд╡рд░реНрдгред C # рдореЗрдВ, рдпрд╣ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╕рд┐рдВрдЯреЗрдХреНрд╕рдЯреЛрдХрди рд╡рд░реНрдЧ рд╣реИред
рд╕рд┐рдВрдЯреЗрдХреНрд╕рдЯреНрд░рд┐рд╡рд┐рдпрд╛ рдЙрди рддрддреНрд╡реЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИ рдЬреЛ рд╕рдВрдХрд▓рд┐рдд рдирд╣реАрдВ рд╣реЛрдВрдЧреЗ, рдЕрд░реНрдерд╛рддреН рд░рд┐рдХреНрдд рд╕реНрдерд╛рди, рд▓рд╛рдЗрдирдлреАрдб, рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдВ, рдкреНрд░реАрдкреНрд░реЛрд╕реЗрд╕рд░ рдирд┐рд░реНрджреЗрд╢ред C # рдореЗрдВ, рдЗрд╕реЗ SyntaxTrivia рдкреНрд░рдХрд╛рд░ рдХреЗ рдПрдХ рд╡рд░реНрдЧ рджреНрд╡рд╛рд░рд╛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
рд╕рд┐рдореЗрдВрдЯрд┐рдХ рдореЙрдбрд▓ рд╡рд╕реНрддреБрдУрдВ рдФрд░ рдЙрдирдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдЙрдкрдХрд░рдг рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рдЖрдк рдПрдХ рдЧрд╣рди рдФрд░ рдЬрдЯрд┐рд▓ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред C # рдореЗрдВ, рдЗрд╕реЗ SemanticModel рдХреЗ рдПрдХ рд╡рд░реНрдЧ рджреНрд╡рд╛рд░рд╛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдПрдХ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдмрдирд╛рдирд╛
рд╕реНрдереИрддрд┐рдХ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдирд┐рдореНрди .NETCompilerPlatformSDK рдШрдЯрдХ рдХреЛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдХрд┐рд╕реА рднреА рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдХреЛ рдмрдирд╛рдиреЗ рд╡рд╛рд▓реЗ рдореБрдЦреНрдп рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ:
- рдХреНрд░рд┐рдпрд╛рдУрдВ рдХрд╛ рдкрдВрдЬреАрдХрд░рдгред
рдЙрд▓реНрд▓рдВрдШрди рдХреЗ рд▓рд┐рдП рдХреЛрдб рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХреНрд╢рди рдХреЛрдб рдкрд░рд┐рд╡рд░реНрддрди рд╣реЛрддреЗ рд╣реИрдВ рдЬреЛ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдХреЛ рдЖрд░рдВрдн рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЬрдм VisualStudio рдХреЛрдб рдкрд░рд┐рд╡рд░реНрддрди рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рддрд╛ рд╣реИ рдЬреЛ рдкрдВрдЬреАрдХреГрдд рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЗ рдЕрдиреБрд░реВрдк рд╣реИ, рддреЛ рдпрд╣ рдкрдВрдЬреАрдХреГрдд рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИред - рдбрд╛рдпрдЧреНрдиреЛрд╕реНрдЯрд┐рдХреНрд╕ рдмрдирд╛рдПрдВред
рдЬрдм рдЙрд▓реНрд▓рдВрдШрди рдХрд╛ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ, рддреЛ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдЙрд▓реНрд▓рдВрдШрди рдХреЛ рд╕реВрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП VisualStudio рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдиреИрджрд╛рдирд┐рдХ тАЛтАЛрдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рддрд╛ рд╣реИред
рдПрдХ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдмрдирд╛рдиреЗ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдХрдИ рдЪрд░рдг рд╣реИрдВ:
- рдПрдХ рд╕рдорд╛рдзрд╛рди рдмрдирд╛рдПрдБред
- рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдХрд╛ рдирд╛рдо рдФрд░ рд╡рд┐рд╡рд░рдг рдкрдВрдЬреАрдХреГрдд рдХрд░реЗрдВред
- рд░рд┐рдкреЛрд░реНрдЯ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдХреА рдЪреЗрддрд╛рд╡рдиреА рдФрд░ рд╕рд┐рдлрд╛рд░рд┐рд╢реЗрдВред
- рд╕рд┐рдлрд╛рд░рд┐рд╢реЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдХреЛрдб рдирд┐рд░реНрдзрд╛рд░рдг рдХрд░реЗрдВред
- рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд╕рд╛рде рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдореЗрдВ рд╕реБрдзрд╛рд░ред
DiagnosticAnalyzer.Initialize (AnalysisContext) рд╡рд┐рдзрд┐ рдХреЗ рдПрдХ рдУрд╡рд░рд░рд╛рдЗрдб рдореЗрдВ рдХреНрд░рд┐рдпрд╛рдПрдБ рджрд░реНрдЬ рдХреА рдЬрд╛рддреА рд╣реИрдВ, рдЬрд╣рд╛рдВ AnalysisContext рд╡рд╣ рд╡рд┐рдзрд┐ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреА рдЧрдИ рд╡рд╕реНрддреБ рдХреА рдЦреЛрдЬ рддрдп рд╣реЛрддреА рд╣реИред
рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдПрдХ рдпрд╛ рдЕрдзрд┐рдХ рдХреЛрдб рд╕реБрдзрд╛рд░ рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдПрдХ рдХреЛрдб рдкреИрдЪ рдЙрди рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреА рдкрд╣рдЪрд╛рди рдХрд░рддрд╛ рд╣реИ рдЬреЛ рд░рд┐рдкреЛрд░реНрдЯ рдХреА рдЧрдИ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╕рдВрдмреЛрдзрд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ (рд╕рдВрдкрд╛рджрдХ рдореЗрдВ рдкреНрд░рдХрд╛рд╢ рдмрд▓реНрдм) рд╕реЗ рдкрд░рд┐рд╡рд░реНрддрди рдЪреБрдирддрд╛ рд╣реИ, рдФрд░ VisualStudio рдХреЛрдб рдмрджрд▓рддрд╛ рд╣реИред RegisterCodeFixesAsync рд╡рд┐рдзрд┐ рдХреЛрдб рдХреЛ рдмрджрд▓рдиреЗ рдХрд╛ рддрд░реАрдХрд╛ рдмрддрд╛рддреА рд╣реИред
рдЙрджрд╛рд╣рд░рдг
рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рд╣рдо рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рд▓рд┐рдЦреЗрдВрдЧреЗред рдЗрд╕ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдЪреЗрддрд╛рд╡рдиреА рджреЗрдиреА рдЪрд╛рд╣рд┐рдП рдФрд░ рдПрдХ рд╕рдВрдкрддреНрддрд┐ рдХреЗ рд╕рд╛рде рдХреНрд╖реЗрддреНрд░ рдХреЛ рдПрдирдХреИрдкреНрд╕реБрд▓реЗрдЯ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдкреНрд░рджрд╛рди рдХрд░рдиреА рдЪрд╛рд╣рд┐рдПред
рдпрд╣рд╛рдБ рдЖрдкрдХреЛ рдХреНрдпрд╛ рдорд┐рд▓рдирд╛ рдЪрд╛рд╣рд┐рдП:

рдЖрдЗрдП рдЬрд╛рдиреЗрдВ рдХрд┐ рдЗрд╕рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдЖрдкрдХреЛ рдПрдХ рд╕рдорд╛рдзрд╛рди рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рд╕рдорд╛рдзрд╛рди рдмрдирд╛рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рддреАрди рдкрд░рд┐рдпреЛрдЬрдирд╛рдПрдВ рд╣реИрдВред

рд╣рдореЗрдВ рджреЛ рд╡рд░реНрдЧреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
1) рдХреНрд▓рд╛рд╕ рдПрдирд╛рд▓рд╛рдЗрдЬрд╝рд░рдкрдмреНрд▓рд┐рдХрдлрд╝рд┐рд▓реНрдбрдПрдирд▓рдПрдЬрд╝рд░, рдЬрд┐рд╕рдореЗрдВ рд╣рдо рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдиреЗ рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд▓рд┐рдП рдЪреЗрддрд╛рд╡рдиреА рдХрд╛ рд╡рд┐рд╡рд░рдг рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВред
рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЧреБрдгреЛрдВ рдХрд╛ рд╕рдВрдХреЗрдд рджреЗрддреЗ рд╣реИрдВ:
public const string DiagnosticId = "PublicField"; private const string Title = "Filed is public"; private const string MessageFormat = "Field '{0}' is public"; private const string Category = "Syntax"; private static DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Warning, isEnabledByDefault: true); public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(Rule); } }
рдЙрд╕рдХреЗ рдмрд╛рдж, рд╣рдо рд╕рдВрдХреЗрдд рджреЗрддреЗ рд╣реИрдВ рдХрд┐ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд┐рди рдорд╛рдирджрдВрдбреЛрдВ рдкрд░ рд╣реЛрдЧрд╛ред
private static void AnalyzeSymbol(SymbolAnalysisContext context) { var fieldSymbol = context.Symbol as IFieldSymbol; if (fieldSymbol != null && fieldSymbol.DeclaredAccessibility == Accessibility.Public && !fieldSymbol.IsConst && !fieldSymbol.IsAbstract && !fieldSymbol.IsStatic && !fieldSymbol.IsVirtual && !fieldSymbol.IsOverride && !fieldSymbol.IsReadOnly && !fieldSymbol.IsSealed && !fieldSymbol.IsExtern) { var diagnostic = Diagnostic.Create(Rule, fieldSymbol.Locations[0], fieldSymbol.Name); context.ReportDiagnostic(diagnostic); } }
рд╣рдореЗрдВ IFieldSymbol рдкреНрд░рдХрд╛рд░ рдХреА рдПрдХ рд╡рд╕реНрддреБ рдХрд╛ рдПрдХ рдХреНрд╖реЗрддреНрд░ рдорд┐рд▓рддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдлрд╝реАрд▓реНрдб рд╕рдВрд╢реЛрдзрдХ, рдЙрд╕рдХреЗ рдирд╛рдо рдФрд░ рд╕реНрдерд╛рди рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рдЧреБрдг рд╣реЛрддреЗ рд╣реИрдВред рд╣рдореЗрдВ рдирд┐рджрд╛рди рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рдЪрд╛рд╣рд┐рдПред
рдпрд╣ рдУрд╡рд░рд░рд╛рдЗрдб рд╡рд┐рдзрд┐ рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдХреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдХреЛ рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛ рд╣реБрдЖ рд╣реИ
public override void Initialize(AnalysisContext context) { context.RegisterSymbolAction(AnalyzeSymbol, SymbolKind.Field); }
2) рдЕрдм рд╣рдо рдХреЛрдб рдХреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдХреЛрдб рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВред рдпрд╣ рдХреНрд▓рд╛рд╕ рдПрдирд╛рд▓рд╛рдЗрдЬрд╝рд░рдкрдмреНрд▓рд┐рдХрдлрд┐рд▓реНрдбрд╕рдХреЛрдбрдлрд┐рдХреНрд╕рдкреНрд░реЛрд╡рд╛рдЗрдбрд░ рдореЗрдВ рд╣реЛрддрд╛ рд╣реИред
рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЗрдВрдЧрд┐рдд рдХрд░реЗрдВ:
private const string title = "Encapsulate field"; public sealed override ImmutableArray<string> FixableDiagnosticIds { get { return ImmutableArray.Create(AnalyzerPublicFieldsAnalyzer.DiagnosticId); } } public sealed override FixAllProvider GetFixAllProvider() { return WellKnownFixAllProviders.BatchFixer; } public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken) .ConfigureAwait(false); var diagnostic = context.Diagnostics.First(); var diagnosticSpan = diagnostic.Location.SourceSpan; var initialToken = root.FindToken(diagnosticSpan.Start); context.RegisterCodeFix( CodeAction.Create(title, c => EncapsulateFieldAsync(context.Document, initialToken, c), AnalyzerPublicFieldsAnalyzer.DiagnosticId), diagnostic); }
рдФрд░ рд╣рдо EncapsulateFieldAsync рд╡рд┐рдзрд┐ рдореЗрдВ рдПрдХ рд╕рдВрдкрддреНрддрд┐ рдХреЗ рд╕рд╛рде рдХреНрд╖реЗрддреНрд░ рдХреЛ рдПрдирдХреИрдкреНрд╕реБрд▓реЗрдЯ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВред
private async Task<Document> EncapsulateFieldAsync(Document document, SyntaxToken declaration, CancellationToken cancellationToken) { var field = FindAncestorOfType<FieldDeclarationSyntax>(declaration.Parent); var fieldType = field.Declaration.Type; ChangeNameFieldAndNameProperty(declaration.ValueText, out string fieldName, out string propertyName); var fieldDeclaration = CreateFieldDecaration(fieldName, fieldType); var propertyDeclaration = CreatePropertyDecaration(fieldName, propertyName, fieldType); var root = await document.GetSyntaxRootAsync(); var newRoot = root.ReplaceNode(field, new List<SyntaxNode> { fieldDeclaration, propertyDeclaration }); var newDocument = document.WithSyntaxRoot(newRoot); return newDocument; }
рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдирд┐рдЬреА рдлрд╝реАрд▓реНрдб рдмрдирд╛рдПрдВред
private FieldDeclarationSyntax CreateFieldDecaration(string fieldName, TypeSyntax fieldType) { var variableDeclarationField = SyntaxFactory.VariableDeclaration(fieldType) .AddVariables(SyntaxFactory.VariableDeclarator(fieldName)); return SyntaxFactory.FieldDeclaration(variableDeclarationField) .AddModifiers(SyntaxFactory.Token(SyntaxKind.PrivateKeyword)); }
рдлрд┐рд░ рдПрдХ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд╕рдВрдкрддреНрддрд┐ рдмрдирд╛рдПрдВ рдЬреЛ рдЗрд╕ рдирд┐рдЬреА рдХреНрд╖реЗрддреНрд░ рдХреЛ рд▓реМрдЯрд╛рддрд╛ рд╣реИ рдФрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред
private PropertyDeclarationSyntax CreatePropertyDecaration(string fieldName, string propertyName, TypeSyntax propertyType) { var syntaxGet = SyntaxFactory.ParseStatement($"return {fieldName};"); var syntaxSet = SyntaxFactory.ParseStatement($"{fieldName} = value;"); return SyntaxFactory.PropertyDeclaration(propertyType, propertyName) .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)) .AddAccessorListAccessors( SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration).WithBody(SyntaxFactory.Block(syntaxGet)), SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration).WithBody(SyntaxFactory.Block(syntaxSet))); }
рдЙрд╕реА рд╕рдордп, рд╣рдо рд╕реНрд░реЛрдд рдлрд╝реАрд▓реНрдб рдХреЗ рдкреНрд░рдХрд╛рд░ рдФрд░ рдирд╛рдо рдХреЛ рд╕рд╣реЗрдЬрддреЗ рд╣реИрдВред рдлрд╝реАрд▓реНрдб рдХрд╛ рдирд╛рдо "_name", рдФрд░ рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдирд╛рдо "рдирд╛рдо" рдХреЗ рд░реВрдк рдореЗрдВ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред
рд╕рдВрджрд░реНрдн
- рдЧрд┐рдЯрд╣рдм рд╕реНрд░реЛрдд
- .NET рдХрдВрдкрд╛рдЗрд▓рд░ рдкреНрд▓реЗрдЯрдлрд╛рд░реНрдо SDK