What tools or techniques do you recommend for discovering C# extension methods in code? They're in the right namespace, but may be in any file in the solution.
Specifically:
How can I find all extension methods (and navigate to them) on the current type in the code window?
I do have Resharper (v4), so if that has a mechanism I'm not aware of - please share!
If you have the source then you can search for this Type identifier using regular expressions. Considering the fact that it has to be the first parameter to the function something like this should do the trick:
\(this:b+:i:b+:i
At least this way you can discover where the extensions methods are defined and add that namespace, then rely on intellisense. Just ran this on a non-trivial project with lots of extensions methods everywhere and it worked a treat. The only false positive was something like this:
if(this is Blah...
Which we can fix by adding static to our search since the extension methods have to be static:
static.*\(this:b+:i:b+:i
This won't work for cases like this:
public
static ExtensionMethod(
this int
iVal) {
}
But that's kind of the limitation of regular expressions. I am sure certain somebodies can tell you all about the pain of using regular expressions to parse a language.
Now, what I think is missing from the IDE is the ability to recognise the extension methods that are in a non-imported namespace. Similar to when you know the classname, if you type it up, the IDE will give you a hint to either use it explicitly or import the namespace. After all, that's how I import all my namespaces and frequently find myself trying to do the same to extension methods.
This is pretty low-tech, but how about Ctrl-F searching for "this:b+MyClassName" ?
If you are using VS which I guess you are intellisense will show all the avialable extensionmethod for a given object for you (marked with a blue thingy added to the usual instance method icon). That list might differ from file to file (a mthod called aMethod might mean two different things in two different files) eventhough the object type is the same (which is based on the way extension methods are found)
If you've got resharper, just hold down the ctrl key and click on the method.
If you have installed the ILSpy extension in Visual Studio (I am using 2022) then you can:
Right click on the class/type and select -> Open code in ILSpy
In ILSpy right click on the type and select -> Analyze
In the Analyze window you will see a node "Extension methods" (if any exists, else no node is shown)
Related
String.Contains optionally takes a StringComparison enum (e.g. StringComparison.OrdinalIgnoreCase). I keep forgetting to specify IgnoreCase, so I want to mark that method as [Obsolete] so I see it in Warnings so I remember to specify the kind of StringComparison.
I'm open to other solutions too, like doing something to "hide" that method and prevent it from being called. The ideal solution doesn't involve Roslyn analyzers though, as I'm using F#.
This solution is interesting, but obviously not ideal.
I would use an Extension Method. Just put it somewhere that's available to all your code, and declare it directly in the System namespace. (I'm not fluent in F#, but this should work.)
namespace System
type String with
member CaselessContains(str) = String.Contains(str, StringComparison.OrdinalIgnoreCase)
Ionide for VS Code supports analyzers. You'd have to write one for the methods you want to disallow.
This question is on behalf of one of my team members: I am a developer in charge of writing the documentation for our product. I have written a tool in C# to output our assembly in markdown style files. In order to facilitate the ease of use for our classes, I wanted to implement a way of linking the class type and property constructs to any MSDN documentation available publicly. For the most part, this was accomplished simply by using the namespace of the class like so:
msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.webcontrol(v=vs.110).aspx
However, I ran into some problems when looking at classes with generic type arguments and properties. They seem to be generated in a special manner that looks like a hashed string, like so:
msdn.microsoft.com/en-us/library/b682ts2x(v=vs.110).aspx
The “b682ts2x” part of the URL is the part that is different.
I would like to know if there is any way I can get in touch with someone who knows how these links are generated, and if there is a way to generate the same exact URL portion (that is, b682ts2x) for any class property using only reflection.
As an alternative approach you could use the same syntax that the F1 help is using when you highlight a class name for example.
As mentioned in Visual Studio intercepting F1 help command
msdn.microsoft.com/query/dev11.query?
appId=Dev11IDEF1&
l=EN-US&
k=k(width);
k(vs.csseditor);
k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.0);
k(DevLang-CSS)&
rd=true
The "k" parameter above is contains the help context inside visual
studio. Help context contains both "keywords" (text strings) and
"attributes" (name/value pairs) which various windows inside Visual
Studio use to tell the IDE about what the user is doing right now.
For example here is one for System.Net.HttpHttpClient.
https://msdn.microsoft.com/query/dev12.query?appId=Dev12IDEF1&l=EN-US&k=k(System.Net.Http.HttpClient);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5);k(DevLang-csharp)&rd=true
Notably when I pressed F1 when highlighting "HttpClient" it assumed I meant ServiceClient.HttpClient so be careful to provide the namespace.
I'm a C#/.net/Visual Studio noob. I inherited a half-completed C# application for a mobile phone. In the course of debugging, I came across several half-finished classes that don't seem to be used anywhere else in the code. Is there a way to get determine if a class definition is instantiated anywhere?
The quickest way (in Visual Studio) is to right-click the type name and select Find all references from the context menu. This will show you all places where that type is referenced in the current solution.
You should get Resharper - it will show "dead" code in grey and make refactoring a lot easier! You may also prefer CodeRush.
Without ReSharper or a similar tool, you can always do a file search for "new ClassName(" in the entire solution.
I usually start with Shift-F12 (or right-click on class name and select "Find All References")
Unless you know the code, and the modules that may use it., CodeRush or Resharper are your better choices.
None of the other answers mentioned the modifiers which can be applied to classes/functions. You certainly want to take scope into consideration before deleting code. You may have other assemblies which use classes/functions.
Remove them from the project and let your unit tests (ahem, you have those right?) and your QA team (you have that right?) identify the problems.
Jokes aside, if it's SO obvious that it's not complete, why not simply remove the code and recompile?
The next steps I would take would be to use a tool like "Find All References" or Resharper (does it even have a feature to do that?)
You can list all the classes (searching for class [a-zA-Z0-9_]+), and then search for new <classname>. The ones not found at the second search are not used. Of course, a simple script in your favourite script language would help.
You'll need however to filter out the classes that are used as base classes of used classes.
Note that this way you'll not find the classes which are used only from unused classes, so several iterations might be needed. Moreover, if some two classes are using each other (but not used from outside), removing them might need additional effort.
Edit:
A better approach would be building dependency tree: for each of the classes you define which class is used by that class, and which class is a base class for that class. This way you find which classes are required for every single class. Then, you can define which classes are required (directly or indirectly) from the class containing Main. All other classes are "unreachable" and therefore not used.
This approach will however remove the classes instantiated by reflection. Well, there is no way to find out at compile time, which classes are going to be instantiated by reflection anyway.
Maybe using the ready tools (like others proposed) is a simpler alternative.
If I go to visual studio and type MyEnumerable., I'll see a list of all the methods that can executed from that object. This list shows extension methods as well, which is great, but is there a way (a keboard shortcut?) to narrow this list down to not include extension methods?
Other than removing using System.Linq from the top of the file, no.
However, you can look at the type in Object Browser, which will not show extension methods.
I don't know if you can but extension methods have a down arrow between the icon and the name, so you can at least tell them apart from the instance methods.
What is the quickest way to determine which members of an enum are not being used?
Comment the enum members out one by one and see if your code compiles. If compilation breaks, the member is used. Although this method only catches compile-time use of your enums. They could be used at runtime.
If you're using ReSharper, click on the enum to check, hit Alt+F7 (Shift+F12 if you're using VS shortcuts), and it'll give you a list of every place it's used in your entire solution.
Being on the safe side you can mark your members with ObsoleteAttribute. Adding [Obsolete(true)] will fail the build if given member is used.
This can obviously be used not only for enums but for nearly anything in .NET.
Resharper is your tool of choice if you need to delete the members from a solution and you're not worried about another uses in different solutions.
Using find references on each member of the enum is the fastest way I can think of.
Ctrl-F and search the entire namespace/project for that member of enum
If you are using VS2005/8 Ctrl-Shift-F so search in the files. This will give you a list of files that you can double-click to goto the lines.
If you don't use VS then you can use WinGrep which will do the same thing (without the double-click feature)
Commenting / uncommenting members. If the compiler does not throw an error the enum member is not used.
Update: As mentioned in the comments this of course only works for projects contained in the solution / the active build configuration. The same holds for the Find References and Ctrl+F methods.
Otherwise there is also the option to do a file search, e.g. using grep. However, this option only allows to do a string-based search and does not resolve any types.