Related
I don't post very often and I have tried to do my research but simply cannot find if my wish is possible using the Visual Studio 2017 Community Editor. I an entry level just-for-fun programmer of C# and am now learning about sub-classes. Here is my wish (and question):
I have developed a class in a separate file (class Parent). It is a very simple class with some public variables. Now in a separate file I have another sub-class Child based of Parent (class Child:Parent). Within the class Child, I use the variables of Parent which are available to me in Child. Everything fine and the compiler doesn't flag my code for errors. So, good or bad, right or wrong, I'm getting the hang of classes and sub-classes.
My wish for the Visual Studio editor is when I look at some variables in my Child class, I find myself wondering, where did those variables come from? Where were they defined? Then I have my ah-a moment and remember they are coming from the Parent class. If I "peek definition' the code, everything is revealed to me very nicely.
But my question to you is can Visual Studio editor somehow colorize these variables that are used in the sub-class but defined in parent class? Especially when the Parent class for me is in another file which is not currently opened?
Just a wish...otherwise what I have is fine but it would be nice when looking at my code after a long time to just see these variables originating from a parent class in another color perhaps.
I did try to go through the Font-Color settings but honestly was overwhelmed and couldn't find a direct hit there.
Any help or comments on this very low priority question would be welcome.
Thank you.
I don't think there is such a feature in VS, you don't need it anyway. According to Crowcoder in the comments, this can be done by writing a Roslyn Analyzer, but I don't think you should do this just because you want to know where are the variables declared. Trust me, you don't need it.
The truth is, in most cases you are not the one who should worry about where exactly a variable is declared when you are reading code. That's the job of the compiler.
If your variables and classes are well-named, you will be able to understand immediately, without thinking about "Wait where does this come from?". For example:
class Slime: Monster {
public Slime() {
Health = 10;
}
}
Given that this code compiles successfully, do you need to worry about where Health is defined? No! It's a slime! Obviously it's gonna have a Health. Do you need to check out the definition to see what it is used for? No! From the name, we can clearly see that it represents how much health is left for the slime.
Basically, what I mean is that if you can write code with well named variables, you will be able to figure out what each variable does without looking at the definition.
Just hovering the mouse over a member variable tells you where it is declared, e.g. if in a sublcass of X and hovering over 'foo' which is an integer declared in X, it will show you int X.foo. It's not exactly what you ask, which as others commented is not easy to get, but it's by far the easiest way and doesn't require Peek Definition.
This question already has answers here:
Instantiating Internal class with private constructor
(5 answers)
Closed 7 years ago.
I'm either googling the wrong thing or trying to head down the completely wrong path (most likely)... but now I'm curious so I thought I'd ask.
Long story short, I'm trying to tap into the underlying "API" framework of Microsoft's Message Analyzer tool for a custom application. I say "API" because there is no formal support for an API, no documentation, and there won't be any in the near future, if ever (so says Paul at Microsoft anyway). So instead I've been using the IL DASM tool to poke around some of the Message Analyzer and PowerShell .dlls to try to get an understanding of how this stuff works; the ultimate goal of course is to use MA's .dlls and drivers to do what I want for the custom app. I'm looking at Microsoft.Protocols.Tools.PowerShell.dll, which has a class (Microsoft.Protocols.Tools.PowerShell.PpkTraceSession) that I'm trying to instantiate:
However, if you look right below it, it says something about the class being private (it's cut off in the picture, but the class does implement IPpkTraceSession and IPpkTraceSessionEx). Sure enough, when I reference this .dll in some C# code and try to instantiate an object, I get a compile error saying its inaccessible due to its protection level:
Windows PowerShell has no problem at all creating one of these objects. It just so happens the printout seen below matches all the properties (not seen in the first picture) of the PpkTraceSession class, so I know Windows PowerShell is working some magic to create an object of that class,, I just can't figure out how since apparently this class is private.
So my question,, what's going on here? I've poked around in a lot of the classes shown in the IL DASM output, and there are a surprising number of them that appear to be private. Maybe it's just my bad practice, but I've rarely if ever used or seen many private classes. It's my understanding they have to be nested in other classes to be of any particular use. If PpkTraceSession is nested in another class, that's not clear from the IL DASM output at all. You may see the IPpkTraceSession(Ex) interfaces above,, if there's a way to access the class properties using those I haven't figured it out yet. Is there anyway to instantiate an object of this class, or am I going about this all wrong?
This might be close to a duplicate, but not quite I don't think. Any help is much appreciated! I clearly don't know much about Windows programming.
yano
EDIT:::::
Just to tie off all the loose ends (in case somebody else makes my mistake), I discovered the source of my confusion a couple of days ago. All the classes indicated as "private" by the IL DASM tool are actually "internal" classes, meaning that they're meant to be visible only within their own assembly. That was my missing piece, I couldn't understand where all these private classes were coming from when C# won't even let you compile a standalone private class (it must be nested within another class). I should've done some more research on IL DASM before I posted a question, but it didn't even occur to me; I thought private meant private. It's my observation that IL DASM does make a distinction between private/internal classes and nested private classes. This issue has also already been addressed here: When I declare a class as internal, why does the IL show it as private? . Thanks for the help everyone!
I suspect that what you are seeing is that other classes, probably deep inside the PowerShell plumbing, might expose some of the properties of the PpkTraceSession class. You might be able to find them by inspecting the intermediate language of the public classes exposed by the same dll THAT contains the private PpkTraceSession class. However, I suspect that you are wasting your time, and will not find a way to use those classes in your own code.
They are marked private because Microsoft has no intention of supporting them, and their behavior might change without notice. That isn't a problem within the PowerShell team, which has access to them, most likely through other private classes. So, if they need to change the way one of those classes behaves, they can do it, and the affected audience is small and easily reachable.
Speaking as a developer, I can think of a host of reasons that Microsoft might not want to support it, such as that it is very fussy, or that doing so would involve disclosing proprietary or patented technology that they have a legal right to keep secret.
Perhaps you could start a campaign to make them public, but you'll need to make a really good case, and convince a lot of other people, preferably people who already pay Microsoft a lot of money, to get behind you.
I'm writing a library that has a bunch of classes in it which are intended to be used by multiple frontends (some frontends share the same classes). For each frontend, I am keeping a hand edited list of which classes (of a particular namespace) it uses. If the frontend tries to use a class that is not in this list, there will be runtime errors. My goal is to move these errors to compile time.
If any of you are curious, these are 'mapped' nhibernate classes. I'm trying to restrict which frontend can use what so that there is less spin up time, and just for my own sanity. There's going to be hundreds of these things eventually, and it will be really nice if there's a list somewhere that tells me which frontends use what that I'm forced to maintain. I can't seem to get away with making subclasses to be used by each frontend and I can't use any wrapper classes... just take that as a given please!
Ideally, I want visual studio to underline red the offending classes if someone dares to try and use them, with a nice custom error in the errors window. I also want them GONE from the intellisense windows. Is it possible to customize a project to do these things?
I'm also open to using a pre-build program to analyze the code for these sorts of things, although this would not be as nice. Does anyone know of tools that do this?
Thanks
Isaac
Let's say that you have a set of classes F. You want these classes to be visible only to a certain assembly A. Then you segregate these classes in F into a separate assembly and mark them as internal and set the InternalsVisibleTo on that assembly to true for this certain assembly A.
If you try to use these classes from any assembly A' that is not marked as InternalsVisibleTo from the assembly containing F, then you will get a compile-time error if you try to use any class from F in A'.
I also want them GONE from the intellisense windows. Is it possible to customize a project to do these things?
That happens with the solution I presented above as well. They are internal to the assembly containing F and not visible from any assembly A' not marked as InternalsVisibleTo in the assembly containing F.
However, I generally find that InternalsVisibleTo is a code smell (not always, just often).
You should club your classes into separate dlls / projects and only provide access to those dlls to front end projects that are 'appropriate' for it. This should be simple if your front-end and the group of classes it may use are logically related.
If not then I would say some thing smells fishy - probably your class design / approach needs a revisit.
I think you'll want to take a look at the ObsoleteAttribute: http://msdn.microsoft.com/en-us/library/system.obsoleteattribute%28v=VS.100%29.aspx
I believe you can set IsError to true and it will issue an error on build time.
(not positive though)
As for the intellisense you can use EditorBrowseableAttribute: http://msdn.microsoft.com/en-us/library/system.componentmodel.editorbrowsableattribute.aspx Or at least that is what seems to get decorated when I add a service reference and cannot see the members.
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.
I'm a pretty new C# and .NET developer. I recently created an MMC snapin using C# and was gratified by how easy it was to do, especially after hearing a lot of horror stories by some other developers in my organisation about how hard it is to do in C++.
I pretty much went through the whole project at some point and made every instance of the "public" keyword to "internal", except as required by the runtime in order to run the snapin. What is your feeling on this, should you generally make classes and methods public or internal?
I believe in blackboxes where possible. As a programmer, I want a well defined blackbox which I can easily drop into my systems, and have it work. I give it values, call the appropriate methods, and then get my results back out of it.
To that end, give me only the functionality that the class needs to expose to work.
Consider an elevator. To get it to go to a floor, I push a button. That's the public interface to the black box which activates all the functions needed to get the elevator to the desired floor.
What you did is exactly what you should do; give your classes the most minimal visibility you can. Heck, if you want to really go whole hog, you can make everything internal (at most) and use the InternalsVisibleTo attribute, so that you can separate your functionality but still not expose it to the unknown outside world.
The only reason to make things public is that you're packaging your project in several DLLs and/or EXEs and (for whatever reason) you don't care to use InternalsVisibleTo, or you're creating a library for use by third parties. But even in a library for use by third parties, you should try to reduce the "surface area" wherever possible; the more classes you have available, the more confusing your library will be.
In C#, one good way to ensure you're using the minimum visibility possible is to leave off the visibility modifiers until you need them. Everything in C# defaults to the least visibility possible: internal for classes, and private for class members and inner classes.
I think you should err on the side of internal classes and members. You can always increase an item's visibility but decreasing it can cause problems. This is especially true if you are building a framework for others.
You do need to be careful though not to hide useful functionality from your users. There are many useful methods in the .NET BCL that cannot be used without resorting to reflection. However, by hiding these methods, the surface area of what has to be tested and maintained is reduced.
I prefer to avoid marking classes as public unless I explicitly want my customer to consume them, and I am prepared to support them.
Instead of marking a class as internal, I leave the accessibility blank. This way, public stands out to the eye as something notable. (The exception, of course, is nested classes, which have to be marked if they are to be visible even in the same assembly.)
Most classes should be internal, but most non-private members should be public.
The question you should ask about a member is "if the class were made public would I want to member the member to be exposed?". The answer is usually "yes (so public)" because classes without any accessible members are not much use!
internal members do have a role; they are 'back-door access' meant only for close relatives that live in the same assembly.
Even if your class remains internal, it is nice to see which are front-door members and which are back-door. And if you ever change it to public you are not going to have to go back and think about which are which.
Is there any reason you need to use Internal instead of Private? You do realise that Internal has assembly level scope. In other words Internal classes/members are accessible to all classes in a multi-class assembly.
As some other answers have said, in general go for the highest level of encapsulation as possible (ie private) unless you actually need internal/protected/public.
I found a problem using internal classes as much as possible. You cannot have methods, properties, fields, etc of that type (or parameter type or return type) more visible than internal. This leads to have constructors that are internal, as well as properties. This shouldn't be a problem, but as a matter of fact, when using Visual Studio and the xaml designer, there are problems. False positive errors are detected by the designer due to the fact that the methods are not public, user control properties seems not visible to the designer. I don't know if others have already fallen on such issues...
You should try to make them only as visible as possible, but as stated by Mike above, this causes problems with UserControls and using the VS Designer with those controls on forms or other UserControls.
So as a general rule, keep all classes and UserControls that you aren't adding using the Designer only as visible as they need to be. But if you are creating a UserControl that you want to use in the Designer (even if that's within the same assembly), you will need to make sure that the UserControl class, its default constructor, and any properties and events, are made public for the designer to work with it.
I had a problem recently where the designer would keep removing the this.myControl = new MyControl() line from the InitializeComponent() method because the UserControl MyControl was marked as internal along with its constructor.
It's really a bug I think because even if they are marked as internal they still show up in the Toolbox to add in the Designer, either Microsoft needs to only show public controls with public constructors, or they need to make it work with internal controls as well.
You should tend toward exposing as little as possible to other classes, and think carefully about what you do expose and why.
It depends on how much control you have over code that consumes it. In my Java development, I make all my stuff public final by default because getters are annoying. However, I also have the luxury of being able to change anything in my codebase whenever I want. In the past, when I've had to release code to consumers, I've always used private variables and getters.
I like to expose things as little as possible. Private, protected, internal, public: give classes, variables, properties, and functions the least amount of visibility they need for everything to still work.
I'll bump something's visibility up that chain toward public only when there's a good reason to.
I completely disagree with the answers so far. I feel that internal is a horrid idea, preventing another assembly from inheriting your types, or even using your internal types should the need for a workaround come about.
Today, I had to use reflection in order to get to the internals of a System.Data.DataTable (I have to build a datatable lightning fast, without all of its checks), and I had to use reflection, since not a single type was available to me; they were all marked as internal.
by default class is created as internal in c#:
internal means: Access is limited to the current assembly.
see
http://msdn.microsoft.com/en-us/library/0b0thckt.aspx
Good Article the defaults scope is internal:
http://www.c-sharpcorner.com/UploadFile/84c85b/default-scope-of-a-C-Sharp-class/
Do not choose a "default". Pick what best fits the visibility needs for that particular class. When you choose a new class in Visual Studio, the template is created as:
class Class1
{
}
Which is private (since no scope is specified). It is up to you to specify scope for the class (or leave as private). There should be a reason to expose the class.