Can I rebuild .NET class from reference source? - c#

I want to add some methods in System.Net.HttpWebRequest class to suit my needs. I tried reflection but it is quite complicated that I need to alter many of its member class method as well.
I am debugging through .NET reference source and I could view the source code of those class. Is it possible for me to copy each of the related class source code and build my own class?

For some classes yes, but for many no.
.NET classes frequently use internal classes that are not exposed publicly, you would not only need to rebuild the class you are interested in but also rebuild all internal references too.
I would recommend not trying to do this and instead either using Extension Methods or if that does not solve your problem ask a new question describing the exact thing you are trying to accomplish and perhaps we can show you a easier way to do it.

Anything's possible.
You have the source code. You know how to copy and paste. Certainly it's possible you could adapt that code for your own purposes.
The question is; is it legal?
To answer that, you need only examine the license for the reference source. To that end, it's perfectly legal, assuming you comply with the MIT license (which is pretty lenient).
The next question is; should you? Probably not. Most likely, you could just add your desired functionality via a helper class or child class, or add new methods via Extension Methods.

Related

Mark method as obsolete for a single project

Due to the way our codebase works, I was advised to not edit certain methods in a shared codebase. Instead, I decided to make a new method that calls the old one and also does the new work our team wanted that method to do. The issue I am foreseeing is not everyone on the team being aware of the new method and still using the old one from the shared codebase.
TLDR:
Shared codebase has SharedCode.Function.
I created OurCode.Function which does some stuff, and then calls SharedCode.Function.
I cannot edit SharedCode.Function or it's containing project.
Is it possible to mark SharedCode.Function as obsolete within our project as a compiler warning somehow or otherwise mark that OurCode.Function essentially replaces it?
EDIT:
Might be pertinent to mention- these are logging functions, so if a dev accidentally calls SharedCode.Function instead of OurCode.Function, the only result is that we capture less data than we desired, it will still compile and run fine. This is a major reason I want to try to make it a compiler warning, so that any dev that doesn't know to use the new function will find out to.
The shortest way is by adding the ObsoleteAttribute as an attribute
to the method. Make sure to include an appropriate explanation:
[Obsolete("Method1 is deprecated, please use Method2 instead.")]
public void Method1()
{ … }
I think the adapter pattern could work wonders in this particular scenario. Essentially you end up creating an abstraction between OurCode and SharedCode.
This isolates access to SharedCode functions so that only the adapter can use the shared code's functions. It may end up that some of the functions in the adapter simply provide a pass through, but some of those functions will have extra logic that needs to be applied (such as in the scenario you are asking about), and having the adapter makes it easy for you to enforce that.
All client code is forced to use the adapter since they cannot directly access the shared code.
If you had access to the source code, I would recommend using the Obsolete attribute that the others have pointed out. But since you don't have access to the code base, I think it could be extremely beneficial to have a layer of abstraction between your code and the non-accessible code.
Now obviously I do not have the full scope of your scenario as to whether or not this makes sense to actually implement, so don't drive blindly, but hopefully this gives you some ideas! :)
Reference the gang of four book or see the following resources:
https://martinfowler.com/bliki/RequiredInterface.html
https://www.dofactory.com/net/adapter-design-pattern
Understanding Adapter Pattern

How can I prevent methods from being added to a class?

I'm trying to find out if there's a way to stop functions/methods from being added (EDIT: by other developers) to a class for the case where the object is a Model or DTO which should not contain methods (to prevent 'abuse' of the Models/DTOs by others, who may try and add 'helper' methods etc).
Is there any way to achieve this?
Use reflection and write a unit test that fails if a model-class has methods.
Mark all you model classes with a custom attribute. Then make a unit test that uses reflection to load a given assembly, iterate all classes in that assembly and check that classes marked with the model attribute does not have methods. This should be fairly straight forward using reflection.
I believe you are trying to solve a procedural issue with code where you should be using communication.
Your colleagues (i assume) are operating on the code files with 'full trust' privileges. If they break that privilege you should open a dialogue. Use the change as an opportunity to educate them on the intended design. Perhaps they are correct and you will be educated!
I suggest simply making the intended design obvious in the class name and with a comment stating the intended nature. Perhaps quote the design document(s) that informed the class.
You cannot hinder anyone with full write-access to your code-base to do so. The only two things you may do to avoid it are create some CodeAnalysis-rule for FXCop as mentioned by Christian.K in the comments or by writing your DTO-class so that it is undoubtly a DTO that should not have any methods by using a unambigious name for the class and if this is not enough provide some code-comments that notifies the coder to do not so.
However you may need some kind of method if using collections e.g. where you will need some kind of comparision if two instances of your DTO are equal, so you have to provide at least an Equals- and GetHashCode-method.
You don't need to use a struct to prevent additions to a class. You can use the sealed keyword
public sealed class MyDTOObject { ... }
Now, you can not inherent a class and also prevent inheritance (which is essentially what you're asking). The very fact of inheriting MyDTOObject is creating a new class which is based off of not equal to, or restricted, or defined in any way by the implementation of MyDTOObject.
You can use an abstract class, to force derived classes to implement certain methods, but not the other way around.
If you want to prevent others from deriving from your class and implementing helper methods, you must use the sealed keyword, or mark the class internal.
You may prevent the class being extended or inherited by marking it final that way nobody would be able to extend your class and hence not being able to add any behavior. But stop and ask yourself whether you want to do that or not, because then you'd be signing an invisible contract that everything ever required by the class is written in the class and this class needs no further addition.
To be clear, I was talking in Java context.

can csharp classes "inherit" the xml documentation like java classes can?

i'm adding comments to some csharp code, and i'm using the xml language provided by .net (or something). i have an interface, and some implementing classes. i have one method in the interface, and it has a comment. in the implementing classes there is no comment on the implementing method.
when one does it like this in java, javadoc automagically uses the interface comment when generating documentation. however, now that i build my project, i get the warning (transalted from swedish, sorry) "the xml comment for the visible type or member bla.blabla.blablabla() is missing (cs1591)". this is only a warning, so not so bad. but!!! it means no xml file was output, so i can't use sandcastle to generate a chm document file, which is my real goal here.... googling the error coded gave nothing :(
do i really have to copy the method comment to all implementing classes? that's like.... code duplication D: is there no way to get the behavior java offers?
I don't know of any way of getting it to happen at XML file generation time, but GhostDoc may well save you from performing the copying manually. I can't say I've used it myself though.
I agree that it would be a valuable feature... particularly if the base class (or interface) documentation changes after the derived classes have been implemented and documented.
You do have to copy the interfaces comments to the implementing class. Generally this is a good thing as the two comments should ideally be different - my opinion (and practise) on this can be summarised as the following:
Interface Comments - Explains what the method/property/etc is supposed/expected to do but should generally not proscribe how any specific implementation should behave
Implementing Class Comments - Explains what the method/property/etc actually does and may include some details of how this is done (typically in <remarks>)
VSdocman can resolve missing XML comments from implemented interfaces automatically when it generates documentation. Moreover, like GhostDoc, it can also explicitly copy inherited comments to the implementing method. Unlike Sandcastle, it's not free.
Well i dont know about Java but Sorry you will have to copy the interface's comments in the implemented class. here is no inbuilt way of doing it...
And yeah consider the suggestion given by JonSkeet

Finding unused classes in C# app

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.

C# code re-use via namespaces

I like to create a file full of custom functions which I have made, which I may use in another project or something. Now I don't fully understand how to go about this, normally in a language like php, you'd just create the php file and then go include("cust_lib.php") or whatever the file is called.
Now I think that the process involves the library having its own namespace, then either go using custom_lib; or custom_lib:: within the script (I don't want to get into a discussion over which is the best way to go here).
Is this right? Or should I create the library and convert it to a .dll, if so how do I go about this, what sort of syntax does a dll have inside it etc.
However if its just file within one project then I don't need to go down that route do I? I can just create the namespace and use that?
This is what I'm working for at the moment, and thought it would be something like this
namespace Custom_Lib{
~~functions to go here~~
}
However the functions have to exist within a class don't they? So that becomes something like
namespace Custom_Lib{
class custom_lib{
public string function1(string input){
return input;
}
}
}
So some help, pointers, examples would be appreciated so I can wrap my head around this
Thanks,
Psy.
(Yes I call them functions, that just comes from a long php/js etc background)
The normal approach would be to create a Class Library project, put your classes and methods in that project, making sure that those you want to expose are public. Then you add a reference to the resulting dll file in the client projects and you will have the functionality from the class library available to you.
Even if you decide to put it all into one single file, I would still recommend you to make it a class library since I imagine that will make it easier to maintain. For instance, consider the following scenarios:
You decide to put it in a file and include a copy of that file in all projects where you want to use it. Later you find a bug in the code. Now you will have a number of copies of the file in which to correct the bug.
You decide to put it in a file and include that same file in all projects. Now, if you want to change some behaviour in it, you will alter the behavior for all projects using it.
In those two cases, keeping it as a separate project will facilitate things for you:
You will have only one copy of the code to maintain
You can decide whether or not to update the dll used by a certain project when you make updates to the class library.
Regarding the syntax issues: yes all methods must exist within a class. However, if the class is merely a container of the methods, you can make it (and the methods static):
public static class CustomLib
{
public static string GetSomethingInteresting(int input)
{
// your code here...
}
}
That way you will not need to create an instance of CustomLib, but can just call the method:
string meaningOfLife = CustomLib.GetSomethingInteresting(42);
In addition to Fredrik Mörk's well-written and spot-on response, I'd add this:
Avoid creating a single class that is a kitchen-sink collection of functions/methods.
Instead, group related methods into smaller classes so that it's easier for you and consumers of your library to find the functionality they want. Also, if your library makes use of class-level variables, you can limit their scope.
Further, if you decide later on to add threading capabilities to your library, or if your library is used in a multi-threaded application, static methods will likely become a nightmare for you. This is a serious concern, and shouldn't be overlooked.
There no question here. You answered it yourself. Yes, you have to construct a class to include all helper methods. And yes, you can either compile it to a dll if you want to reuse in multiple projects it or just add the source file to the project.
Usually I declare the helper class and all functions as static to avoid initiating the class each time I use it.

Categories

Resources