Visual Studio 2008 / C# : How to find dead code in a project? - c#

How do I find dead code in a Visual Studio 2008 C# project?
Like unused classes, unused variables or unused resources?

You can try FxCop, which is integrated in Visual Studio 2008 by the name of Code Analysis. You just have to right click the project file and 'Run Code Analysis'.
FxCop is an application that analyzes managed code assemblies (code that targets the .NET Framework common language runtime) and reports information about the assemblies, such as possible design, localization, performance, and security improvements.
The active rules can be configured in the Code Analysis section of the project properties. For example some rules relevant to the case in hand are present in Usage Rules and Performance Rules:
CA1801: Review unused parameters.
CA1811: Avoid uncalled private code.
And for greater flexibility you also write your own custom rules (Tutorial on writing your own Code Analysis rule).

Install JetBrains ReSharper which will highlight the unused code for you.

A very useful tool for this is the NDepend dependency analysis tool. You can load your Visual Studio project into this, and it will analyse the dependencies of all your assemblies, types and methods. It gives you a wealth of information on the dependenices, including (but in no way limited to!) methods/types that are not used by anything at all.
You can view the dependencies either graphically, or in a list, and can write your own custom dependency queries such as this - a simple CQL query show potentially unused methods :
SELECT
METHODS // Get me a list of methods
WHERE
MethodCa == 0 // Where their afferent coupling is zero, (afferent coupling being the number of other methods that call it)
A highly recommended tool.

Shift + F12 in VS is useful for a quick check :)

While I wouldn't recommend this for a large code base you can do a certain amount manually.
If you right click over a method or class and then select "Find Usages" you'll get an output of all places where it's referenced. Obviously this will be empty if it's not used.
For ongoing clean up I'd install ReSharper

Related

Configure Visual Studio Autocomplete to list classes outside of namespace?

When I type in the autocomplete/intellisense for Visual Studio, if the thing I'm trying to reference isn't part of the current namespace, it won't show it at all.
Is there a way to get the Visual Studio autocomplete to include the names of classes that are in my solution, but not necessarily in my current namespace? This would be similar to how the autocomplete for Typescript works in VS Code - it lists things that match what you type, then automatically imports them upon completion.
IntelliJ autocomplete for Java also works the way I'd like it to - when I start typing, it gives me a list of all the various things that match, including their classpath, so I can pick the one I need.
If this is a thing for Visual Studio, I can't figure out how to configure it to do this.
ReSharper you will do the job (expensive but powerful).
https://www.jetbrains.com/help/resharper/Coding_Assistance_Code_Completion_Auto.html
If you need just to extend VS intellisense you can try this one:
https://marketplace.visualstudio.com/items?itemName=Dreamescaper.IntellisenseExtender2019
With Visual Studio 2019 now there is an IntelliSense option to "Show items from unimported namespaces" to achieve similar functionality to ReSharper. You still need to have added a reference to the project though.
I believe the issue is due to a lack of a reference from one project to the other. In the project you're working on, you have to manually add a reference to the project you're trying to reach.
Right-click the project node in Solution Explorer > Add > Reference > Projects > (your project name)
Then in the code, you probably want to include a using statement to reference the namespace and classes. Something along the lines of: using YourNamespace; using YourNamespace.YourClass; and so on depending on your needs.
But with the reference added, VS should be able to find the namespaces (similar to adding an external library).
The thing to keep in mind is that IntelliJ, and the autocomplete features in VS Code work much differently than Intellisense for C#. The former basically just looks through the code for similar usages, and infers from that that it's a potential member/function of what you're referencing. You'll see this in regular text editors like Atom and whatever. Autocomplete for C# is much more involved and VS does a lot more with reading the actual code and is less about inferring. I'm guessing this was done because it's easier for them to implement just based on the nature of the languages.

Enable native code debugging to deep into COM-object

I have some code that uses a 3rd-party lib (ArcObjects) exposed by COM. So for instance there´s the IGeometry-interface.
IGeometry geometry = GetGeometry();
Now when I want to look at the objects members I open a QuickWatch:
I´ve read several issues that all point to the "enable native code debugging"-option in Visual Studio 2015. I´ve already enabled that option to no avail.
How can I get the debugger to expose the members of the COM-object?
EDIT: When working with VS2010 and .NET 3.5 this works:
Enabling unmanaged debugging can only have a useful side-effect if you also have the PDB and the source code for the component. You don't, vendors of these kind of components don't disclose it. The only reason you can see anything at all is because you let VS generate the interop assembly for the COM component. Which converts the declarations in the type library for the component into equivalent .NET types. Like IGeometry, most probably actually a C++ class under the hood.
Which is the big difference between the top view and the bottom screen-shots. Starting with VS2010 and .NET 4.0, this interop assembly is no longer needed. Called "type embedding", in general a highly useful feature, it avoids the need to deploy the PIA for a component. A very big deal in particular for Office interop.
Type embedding aggressively removed types and members that are not used in the source code. What is left is embedded into your final assembly, thus removing the need to deploy the interop assembly or PIA. Or in other words, you can't see IGeometry.Envelope back in the debugger because your source code doesn't use the property. It got stripped by the type embedding plumbing.
That is easy to fix. Select the COM reference in your project's Reference node and set its "Embed Interop Types" property to False. You can leave it that way after testing, don't forget then to also deploy the interop assembly.
As suggested in the comments I posted that question on gis.stackexchange.com also, from which I quote our solution:
In Visual Studio under Tools-->Options-->Debugging enable the option
"Use Managed Compatibility Mode".

Can multiple .vsix with VB/C# Diagnostic Analyzer/CodeFix/AutoUpdate cause performance issue?

I'm implementing a system that will implement code quality as part of in-house quality measures. I've structured the system in two possible ways of implementation as follows:
Implementation 1: (Already implemented)
An AutoUpdate extension (Stub)
C# CodeQualityPlugin (Roslyn C# Diagnostic Analyzer & Code Fix)
VB CodeQualityPlugin (Roslyn VB Diagnostic Analyzer & Code Fix)
The AutoUpdate feature checks for any update of itself and other CodeQuality plugins by verifying their version number. It halts update for the next 7 days once the CodeQuality plugins are updated.
This is presently my idea of implementation, but the development is halted citing the possible performance issue related to number of extensions in this implementation and that there might be a Visual Studio limitations in its usage/performance (as mentioned by the team)
Implementation 2: (Suggested)
C# CodeQualityPlugin (Roslyn C# Diagnostic Analyzer, Code Fix, AutoUpdate)
VB CodeQualityPlugin (Roslyn VB Diagnostic Analyzer, Code Fix, AutoUpdate)
In this the update functionality is individually triggered and maintains the single responsibility philosophy.
I'm not sure if the AutoUpdate project (Which uses the menu command template) and C#/VB CodeFix/DiagnosticAnalyzer project (Roslyn Template ) can co-exist?
Implementation 3: (One of the opinion)
CodeQualityPlugin (Roslyn C#/VB Diagnostic Analyzer, Code Fix, AutoUpdate)
I'm not even sure if these three can co-exists in a single vsix.
So my question what could be the performance issues in the above three scenarios, and how do we implement the plugin that we develop based on the Roslyn template into a normal menu command template extension for visual studio.
---EDIT---
To summarize the requirement was as follows
Coexistence: VSPackage extension (to extend shell command component of Visual Studio) and Managed Extensibility Framework/MEF extensions (to customize and extend the editor to include Roslyn DiagnosticAnalyzer/CodeFix), should coexist either in
Single VSIX
Maximum 2 VSIXs
Performance: The coexistence shouldn't affect the performance and AutoUpdate taken care by the VSPackage extension should not create redundant service calls.
No.
The only real "performance problem" you can have is putting the C# and VB ones in the same assembly (note, not VSIX), which would mean when we have to load one we load the others.
From the perspective of MEF, we just get a list of exports back: we don't know which VSIXes they're from, and it's hard to figure out if even if we wanted to. So which VSIX you put stuff in doesn't matter at all: divide them up based upon what makes sense for your users.
Caveats of Roslyn and VSIX packaging:
As mentioned by Srivatsn
Extensions that refer to both Microsoft.CodeAnalysis.CSharp and Microsoft.CodeAnalysis.VisualBasic will
Load both the compilers even if we try to open a C# project, this is not ideal.
If we have to analyze the symbols ISymbolAnalyzer,where you are analyzing just the symbols and not the syntax nodes, then we should adopt a single language-agnostic analyzer. This means we don't have to refer any C#/VB dlls (Even Microsoft is thinking about implementing more language-agnostic analyzer). Include two export attributes - one for each language, these attributes tell VS to instantiate and call these analyzers when the respective language is contained in the solution.
Compilation as a process leaves the memory after the compilation is done, but since there is a compilation happening at almost every keystroke and if the analyzer refers to both c# and VB, it will bring both compilers into memory. Since there is a persistence characteristic, it could be a problem if there is a large project under the solution (This is my typical production scenario)
There is a confusion whether the compiler is loaded when the respective syntax method is invoked or on instantiation of the exported analyzer (which is again being filter through the MEF export attribute by mentioning the respective language use case) since he also mentioned that the if a method that refers to both kind of syntax node might make the JIT compile and load the dlls.
Any analyzers linked to menu command would be VS specific and if they are linked to the project then it will participate in the build as well, even outside of the VS through MSBuild
VSIX should be able to export multiple components for extending both of those extension points.
As mentioned by VSadov
Persistence of the syntax tree data-structure and the need to re-do analysis at every keystroke(delta-compilation: this is what Srivatsn's compilation means) made them design the red-green tree method which helps in the performance of the delta-compilation.
As mentioned by SLaks
MEF exports doesn't make any difference whether they are packaged in a single VSIX or not (but it should be noted that there is a performance issue related to combining both type analyzers into a single assembly which is an MEF export)
As mentioned by Kevin Pilch
Although it doesn't matter where these assemblies are packaged in unless they are separate in concern when it comes to language specific references.
Virtual memory will be reserved if the analyzer references both the C# and VB specific Roslyn assemblies and these compiler assemblies are large
The performance problems being Disk loading and JIT costs (I'm not sure how there is a JIT cost if there is no compilation and only reference in it), but since there is an address space reserved there could be an issue in VS (I'm not sure how that will be an issue.)
What Microsoft does, according to him, is to create three projects to deal with this (According to Srivatsn Microsoft is still trying for language-agnostic analyzers)
Shared (No language specific binaries in it)
C# specific (+ shared libraries)
VB Specific (+ shared libraries)
If no language specific binaries are referred and if the MEF exports are appropriately attributed with ContentType or LanguageName then the above issue can be solved
We can bundle additional assemblies into a single VSIX (by embedding the other project in it) and VS will load each independently
Final Implementation:
So Finally I came to a conclusion after discussion with my team as follows
A single VSIX implementation by embedding the following projects in it
Update plugin
Checks if update was present in the past 7 days
Then checks for the version number of the Plugin from server side via a JSON request
Then downloads the plugin from the server, stores the download date in VS settings for initial check
Disables the previous plugin
Uninstalls the previous plugin
Installs the new plugin
This functionality is triggered when
The VS loads
Manual menu command (which should override the download date check)
C# plugin
Implements and refers only rules for C#
VB Plugin
Implements and refers only rules for VB

how to put language resources in a separate project to generate satellite assemblies

I've been using http://www.codeproject.com/Articles/30035/Simple-WPF-Localization project to localize an app because (well) it's simple and straight-forward and supports dynamic language change.
I put all the language resources in the main project (i.e. resources.resx, resources.ja-JP.resx). That way the satellite assemblies get generated automatically and into the correct folder structure.
However, i would like to put all the language resources (except the default/neutral one - resources.resx) in a separate project. With that, i don't need to rebuild the main project (which has the application source) if i only needed to change something in one of the translations.
So, i would like to know if there is a standard way (or at least a very straight-forward way) of creating a VS project that only contains language resources.
I already tried creating an empty project and setting the output to class-library and the assembly to match my executable's name. It does create the correct satellite assemblies in the correct folder but it also generates a dll. It would be real simple if there's a project-type for c# or wpf that are completely language resource-only but i can't seem to find any references about it.
(btw, i'm using VS 2010 with WPF project)
thanks for any help!
(late reply, but for the community)
Depending on exactly what one want to achieve, building satellite assemblies from the command line might be the ticket for you (using command line tools resgen and al.exe).
I had to do this to enable non developers to modify resources, and without going through the development team/build/deploy cycle, have their changes take effect and allow them to validate.
This is mentioned in a lot of places in the MSDN docs, but I haven't seen many end-to-end samples demostrating it:
https://github.com/JohanPGunnarsson/LocalizedResx

Build entire solution but add global Conditional Compilation Symbols for just one project

I hava a quite complex solution, containing 10 projects aside from Test projects.
It is a network of distributed applications & services that communicate using remoting; therefore having the proper referenced assemblies (& versions) is crucial. That's why I want the whole thing to be compiled and schrink-wrapped in ONE build.
One of the applications is a demo/analysis-tool that runs a subprocess of another - much bigger - application based on the user's input and displays the results; That way engineers have a tool to help tweak their settings for "the big computation". Obviously that subprocess is contained in another assembly, and a big part of te results presented to the engineers is generated by
#if ENABLE_TRACE_MATCHING
Trace.WriteLine("Some engineering output");
#endif
My problem is that Conditional Compilation Symbols in the project settings are limited to that project's assembly, and do not propagate over referenced assemblies.
How can I configure my build in such a way that all projects will be built without ENABLE_TRACE_MATCHING being defined, except for the one debug/analysis-app project where all referenced projects/assemblies must be compiled with ENABLE_TRACE_MATCHING being defined
I also cannot replace #if ENABLE_TRACE_MATCHING by #if DEBUG, since that would enable a whole lot of different output our engineers wouldn't know how to handle.
Thanks in advance.
PS: If you think my code smells, then I agree. Additionally: It's mostly not my code ;)
You need to learn more about Microsoft Build, which is an out-of-the-box Microsoft .NET tool present in any framework's installation.
Using MSBuild you can define these "symbols" (properties) and a batch of commands (targets).
That's you can create a MSBuild script that imports default Visual Studio targets from all projects in your solution, and declare in the script these properties ("symbols").
In fact, the property to set such symbols already exists: "DefineConstants".
So, since you have it, you can have that MSBuild script that provides that property value, re-declaring it there, so, ALL MSBuild targets will be knowing about these symbols.
EDIT:
Check this other question too:
msbuild, defining Conditional Compilation Symbols

Categories

Resources