Long Version
In the web app that I work on, we put all our translations into .resx files that we then refer to by calling Resources.FileName.KeyName (as specified in the "To retrieve global resources using strong typing" section of http://msdn.microsoft.com/en-us/library/ms227982%28v=vs.100%29.aspx).
In some places we retrieve the value directly, but in a lot of cases we retrieve the value to be used in JavaScript, so we need to do something like this: HttpUtility.JavaScriptStringEncode(Resources.FileName.KeyName)
The problem is that there are thousands of these kinds of lines that need to be wrapped with a call to HttpUtility.JavaScriptStringEncode retroactively.
There has to be a better way to do this rather than going through the entire source code and manually wrapping each reference to the resources.
TL;DR Version
I need a better way of wrapping each Resources.FileName.KeyName call with HttpUtility.JavaScriptStringEncode() than manually going to each reference and adding it myself.
I was unable to come up with a true solution for this so I decided to solve this using regular expressions.
Now, the problem is that we are still using Visual Studio 2010, which has it's own subset of regex that is not compatible with a lot of advanced trickery, so assertions were not an option.
Instead, I just found all instances of <Resources\.Thread.{[a-zA-Z0-9_]+} and replaced it with HttpUtility.JavaScriptStringEncode( Resources.Thread.\1 ).
This can create duplicate calls though if you already had a few instances that were properly calling JavaScriptStringEncode, so unfortunately following that I had to find all instances of HttpUtility.JavaScriptStringEncode\(HttpUtility.JavaScriptStringEncode\( {[a-zA-Z0-9_ \.\)]+}\)\) and replace it with HttpUtility.JavaScriptStringEncode( \1).
The lack of space at the end of the replace string inside the parenthesis is intentional for formatting.
There are other derivatives to sort out (spaces between parenthesis) but this is the baseline. After a few more searches to clean up duplicate calls, it was done.
Not my best work, but the best I could come up with short of upgrading to Visual Studio 2012/2013 and using real regex with assertions to do it all in one shot (which is obviously recommended if you can do it).
Related
You load a foreign code example with libraries attached to it in Visual Studio. Now there is a method that you want to reuse in your code. Is there a function in VS that lets you strip the code from all unnecessary code to only have code left that is necessary for your current method to run?
It is not about the library. Loading a .sln or .csproj and having classes over classes when you just want one method out of it is a waste of performance, ram and space. It is about code you can easily omit or references(what I call libraries) you can easily omit. A part-question of this is: Which "using" statement do you need that is only necessary for your current method and the methods that pass paramaters to it? In short, showing relevant code only. Code that is tied to each other.
Let's use an example: You go to github and download source code in c#. Let's call the solution S. You open S in Visual Studio. You don't disassemble, you just load the source code of S, that is there in plain text. Then you find a method M - in plain text - that you want to use. M contains some objects whose classes were defined somewhere in the project. The goal is to recreate the surrounding only for this method to copy & paste it into my own solution without having red underlined words in almost every line within the method
after reading the question and the comments, I think I have a vague idea what you are referring to.
In case we ignore the context of the method you are referring, you can extract any code piece from a "library" by using a .NET decompiler and assembly browser.
There are many of them for free, such as:
dotPeek,
ILSpy
...
This will allow you to see the method's code. From there on, you can proceed as you like. In case your copy the method to your code base, you might still have to change it a bit in order to adapt it to work with your objects and context. If you don't, this will give you insight on how the method works and might help you to understand the logic, so you can write your own.
Disclaimer: With this post, I am pointing out that it is possible to extract code from an assembly. I am not discussing the ethics or legal perspective behind such actions.
Hope this helps,
Happy Coding!
If it`s just one method, look at the source code and copy it to your libarary. Make sure you make a comment where you obtained the code and who has the copyright! Don't forget to include the licence, which you should have done with a libary reference anyway.
That said it is currently not (official) possible to automaticly remove unused public declared code from a library (assembly). This process is called Treeshaking by the way. Exception: .NET Native.
But .NET Native is only available for Windows Store Apps. You can read more about it here.
That said, we have the JIT (Just in Time)-Compiler which is realy smart. I wouldn't worry about a few KB library code. Spend your time optimizing your SQL Queries and other bottlenecks. The classes are only loaded, when you actualy use them.
Using some unstable solutions or maintaining a fork of a library, where you use more then one method (with no documentation and no expertise, since it is your own fork) isn't worth the headache, you will have!
If you realy want to go the route of removing everything you do not want, you can open the solution, declare everything as internal (search and replace is your friend) and restore the parts to public, which are giving you are Buildtime error / Runtime error (Reflection). Then remove everything which is internal. There are several DesignTime tools like Resharper, which can remove Dead Code.
But as I said, it's not worth it!
For .NET Core users, in 6-8 weeks, we have the .NET IL Linker as spender has commented, it looks promising. What does this mean? The .NET framework evolves from time to time. Let it envolve and look at your productivity in the meantime.
I have to work with an old version of Mono in Unity projects. I find myself recreating some classes and extension methods that exist in later versions of .NET. Should I be marking these with an attribute that will make it easy to take them out at a later point, just wait for the inevitable errors, and delete the duplicate code, or take some other approach I'm not familiar with yet? If the attribute route is the way to go, is there already an appropriate attribute created for this kind of thing?
Here's what I'd like:
[PresentInDotNET(3.5)]
I fill in the version and get alerted when the framework is at that level or higher.
Split them off to a separate assembly, and change the set of assemblies that make up the final delivery based on the .NET version. You need to rebuild your main assembly to refer to the correct assemblies (depending on whether Foo is in MySystem or System), but as long as you keep namespaces identical, that's all. If you are not even interested in keeping compatibility with older versions, you can simply delete classes from this assembly as they become available.
Alternatively, if the classes/extension methods you are recreating are not interesting (in the sense that you gain nothing by having .NET supply them for you), simply put them in their separate namespace and accept that you are duplicating code already present in newer versions. It doesn't matter a whole lot which assembly gets the job done, after all, as long as it happens.
Whatever you do, try to avoid going the route of #ifdefs, runtime discovery, and other conditional code, as this is much harder to maintain.
How about adding "// TODO" comments for places like this? Visual Studio will display these in the Task window and you can get at them pretty easily.
I often type string in c# when actually I want to type String.
I know that string is an alias of String and I am really just being pedantic but i wish to outlaw string to force me to write String.
Can this be done in ether visual studio intellesence or in resharper and how?
I've not seen it done before, but you may be able to achieve this with an Intellisense extension. A good place to start would be to look at the source for this extension on CodePlex.
Would be good to hear if you have any success with this.
I have always read in "Best Coding Practices" for C# to prefer string, int, float ,double to String, Int32, Single, Double. I think it is mostly to make C# look less like VB.NET, and more like C, but it works for me.
Also, you can go the other way, and add the following on top of every file
using S = System.String;
..
S msg = #"I don't like string.";
you may laugh at this, but I have found it invaluable when I have two similar source codes with different underlying data types. I usually have using num=System.Single; or using num=System.Double; and the rest of the code is identical, so I can copy and paste from one file to the other and maintain both single precision and double precision library in sync.
I think ReSharper can do this!
Here is an extract from the documentation:
ReSharper 5 provides Structural Search and Replace to find custom code constructs and replace them with other code constructs. What's even more exciting is that it's able to continuously monitor your solution for your search patterns, highlight code that matches them, and provide quick-fixes to replace the code according to your replace patterns. That essentially means that you can extend ReSharper's own 900+ code inspections with your custom inspections. For example, if you're migrating to a newer version of a framework, you can create search patterns to find usages of its older API and replace patterns to introduce an updated API.
cheers,
Chris
I require the ability to preprocess a number of C# files as a prebuild step for a project, detect the start of methods, and insert generated code at the start of the method, before any existing code. I am, however, having a problem detecting the opening of a method. I initially tried a regular expression to match, but ended up with far too many false positives.
I would use reflection, but the MethodInfo class does not reference the point in the original source.
EDIT: What I am really trying to do here is to support pre-conditions on methods, that pre-condition code being determined by attributes on the method. My initial thought being that I could look for the beginning of the method, and then insert generated code for handling the pre-conditions.
Is there a better way to do this? I am open to creating a Visual Studio Addin if need be.
This is a .NET 2.0 project.
Cheers
PostSharp or Mono.Cecil will let you do this cleanly by altering the generated code without getting into writing a C# parser which is unlikely to be core business for you...
Havent done anything of consequence with PostSharp but would be guessing its more appropriate than Mono for implementing something like preconditions or AOP. Alternately you might be able to do something AOPy with a DI container like Ninject
But of course the applicability of this idea Depends - you didnt say much other than that you wanted to insert code at the start of methods...
EDIT: In light of your desire to do preconditions... Code Contracts in .net 4 is definitely in that direction.
What sort of a tool do you have? Whats wrong with having a single Mono.Cecil.dll DLL shipped? Either way something other than a parser is the tool for the job.
I am sure there is an easier way but this might be a good excuse to take MGrammer for a spin.
So, every time I have written a lambda expression or anonymous method inside a method that I did not get quite right, I am forced to recompile and restart the entire application or unit test framework in order to fix it. This is seriously annoying, and I end up wasting more time than I saved by using these constructs in the first place. It is so bad that I try to stay away from them if I can, even though Linq and lambdas are among my favourite C# features.
I suppose there is a good technical reason for why it is this way, and perhaps someone knows? Furthermore, does anyone know if it will be fixed in VS2010?
Thanks.
Yes there is a very good reason for why you cannot do this. The simple reason is cost. The cost of enabling this feature in C# (or VB) is extremely high.
Editing a lambda function is a specific case of a class of ENC issues that are very difficult to solve with the current ENC (Edit'n'Continue) architecture. Namely, it's very difficult to ENC any method which where the ENC does one of the following:-
Generates Metadata in the form of a class
Edits or generates a generic method
The first issue is more of a logic constraint but it also bumps into a couple of limitations in the ENC architecture. Namely the problem is generating the first class isn't terribly difficult. What's bothersome is generating the class after the second edit. The ENC engine must start tracking the symbol table for not only the live code, but the generated classes as well. Normally this is not so bad, but this becomes increasingly difficult when the shape of a generated class is based on the context in which it is used (as is the case with lambdas because of closures). More importantly, how do you resolve the differences against instances of the classes that are already alive in the process?
The second issue is a strict limitation in the CLR ENC architecture. There is nothing that C# (or VB) can do to work around this.
Lambdas unfortunately hit both of these issues dead on. The short version is that ENC'ing a lambda involves lots of mutations on existing classes (which may or may not have been generated from other ENC's). The big problem comes in resolving the differences between the new code and the existing closure instances alive in the current process space. Also, lambdas tend to use generics a lot more than other code and hit issue #2.
The details are pretty hairy and a bit too involved for a normal SO answer. I have considered writing a lengthy blog post on the subject. If I get around to it I'll link it back into this particular answer.
According to a list of Supported Code Changes, you cannot add fields to existing types. Anonymous methods are compiled into oddly-named classes (kinda <>_c__DisplayClass1), which are precisely that: types. Even though your modifications to the anonymous method may not include changing the set of enclosed variables (adding those would alter fields of an existing class), I guess that's the reason it's impossible to modify anonymous methods.
It is a bit a shame that this feature is partially supported in VB but not in C#:
http://msdn.microsoft.com/en-us/library/bb385795.aspx
Implementing the same behaviour in C# would reduce the pain level by 80% for functions that contain lambda expressions, where we do not need to modify the lambda expressions nor any expression that depends on them, and probably not for a "monster cost".
Restarting a unit test should take a matter of seconds, if that. I've never liked the "edit and continue" model to be honest - you should always rerun from scratch IMO, just in case the change midway through execution would have affected the code which ran earlier. Given that, you're better off using unit tests which can be run with a very quick turnaround. If your individual unit tests take an unbearable time to start, that's something you should look at addressing.
EDIT: As for why it doesn't work - you may find that it works for some lambdas but not others. Lambda expressions which don't capture any variables (including this) are cached in a private static variable, so that only one instance of the delegate is ever created. Changing the code means reinitialising that variable which could have interesting side-effects I suspect.
I just want to point out that Visual Studio's consideration of "editing" in this context is (or at least can be) a bit stupid. When I was checking out an older commit as part of doing an interactive rebase in git and then attempting to run an unit test, that resulted in 9 error (with ENC0014 and some others).
So with no files modified, every time I attempted to debug the unit test I got those errors. Restarting Visual Studio made the errors go away, so I guess that the underlying problem is missing cache invalidation where Visual Studio does not detect/react to files being changed outside editing via its editor windows.