Contractor changing code style [closed] - c#

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I currently support an application at work that was originally written by a team of four but has now reduced to just me. We recently got a contractor in to look at some performance issues while I'm occupied with other things.
While the contractor has appeared to do a good job with the performance, they have also gone through large amounts of the code replacing the pre-existing style with their personal preference.
Unfortunately we don't have a coding standards doc, just a general rule to adhere to c# general rules.
As an example of what they've done, it includes:
removing nearly all the uses of the 'var' keyword
Anywhere with an if statement and a single line, they've added curly braces
Removing most of the lambdas and replacing it with more verbose code
Changing method signatures so every parameter is on a separate line rather than one line
We also operate a TDD policy but the test coverage, especially on the performance specific parts, is very low leaving very little documentation on what they've changed and making it even harder as their checkin comments aren't particularly helpful and the actual functional changes are lost amongst the swathe of 'tweaks'.
How do I talk to the contractor about this? Obviously there's not much impetus on them to change it given they have no responsibility to support the project and they don't seem particularly receptive to change.
Or should I just put up with it for the short duration of the contract then change everything back to the code formatting we used before?
Made community-wiki 'cos there's probably not one right answer here.

Anywhere with an if statement and a single line, they've added curly braces
This one and the only one may be beneficial.
removing nearly all the uses of the 'var' keyword
Removing most of the lambdas and replacing it with more verbose code
Changing method signatures so every parameter is on a separate line rather than one line
These ones make little sense to change.
Tell him he's not authorized to restyle code. You won't be paying for the time wasted for these activities and they'll have to use their own time to put things back. That should provide a refreshment.
These things should be discussed in advance. You should state clearly what activities are allowed and what not. Not a long ago there was another similar question here about a contractor who would put his initials all over the code including database entities. It was some perverse kind of self-promotion for which there is no place in someone else's code.
P.S. There may also be a possibility that by doing all these things your contractor is artificially creating extra workload to bill you more hours.

I'm a contractor (sometimes) and if I did this I would expect to be shown the door with great speed and no payment. Seriously, this person is hired by you and should be doing exactly what he is told to do, no more and no less. And don't worry about being "nice" - contractors don't expect that from permies.

How do I talk to the contractor about this?
Politely: explain why you want to minimize changes to the source code.
ALternatively, have a code inspection of the changes before check-in: and don't allow check-in of changes that you don't understand/don't want/haven't been tested.

Implement FxCop - this should be your first line of defense. Also if you use source control (if you don't then implement one ASAP), make sure to use dev labelling (only build on file that have been labelled for the build), and don't give him rights to move labels on the files. This way you can scrutinize his changes, and refuse to dev label his code until it meets your standards. Whatever he codes won't make it into QA until you move the dev label to the revision in question, so he's pretty much at your mercy there. Note that some shops don't use a single label for their sandbox builds, they like to apply new labels even to the sandbox, so you may be inclined to do that as well.

The problem has happened now, and as the other said it's an unjustifiable waste of your money and it's outright impolite (as correct as the curly braces thing may be).
Certainly to help prevent future problems, and maybe helpful to resolve this, I'd advise you set up a stylecop implementation - at the very least they can't fail to be unaware of when they are breaking your rules.

I think we all know the temptation of seeing coded we think is "not the way I'd do it". But we resist it.
I would have a chat about it with your boss first to get their take on it. But the first thing that springs to mind is that unless you specifically asked the contractor to do the work, he was not doing what he was hired to do, regardless of any benefit he thinks he may have been adding. So there needs to be a discussion about that.
The next thing that sprung to mind is that regardless of how good they may be or well intentioned, people who make bulk changes without discussing it with the owners of the code are bad news. They will piss people off, or worse introduce bugs and unforeseen behavior that you will have to clean up. He needs to be set straight that doing this sort of thing without permission on other peoples code is not acceptable.
When I see things I don't like in others code which are serious enough to warrant attention, I check with the owners of the code first. Even if there are obvious bugs, it
s their code and their decision about cleaning it up, not mine.

As others have said, these changes are simply for coding style. If he is there to improve performance, he is wasting time with these changes. If he can't cite how these changes will improve performance, then his OCD is just running up the bill.
I would say, "I appreciate your changes to the coding style, but lets focus on non-style changes to areas of the code that are causing the slowdown."

If a contractor did wholesale reformatting of code without authorization, I'd give him one and only one change to put things back the way they were -- and on his own time.
In addition to the valid points others make, consider the version-control nightmare this causes. Instead of the clean progression of a few lines added here, a few lines changed here, you now have this "rift" in your source control database, so that any comparisons between versions before and after this contractor's "improvements" will be meaningless.
Have the contractor back out all of his changes. Today. And on his own time.

This is quite common my experience, that people can't resist making 'improvements' and suddenly you find you're billed for stuff you didn't want. Sometimes I'm sure it's done deliberately to get more paying work, but mostly I think it's a developer getting side-tracked and unable to deal with leaving 'wrong' code.
It might require a bit of a battle, but you basically have to keep reiterating "don't change anything you're not asked to work on". Depending on his personality, you might just have to ask once nicely, or get someone higher to force him.

First, as others have said. You are paying the bill. He is not an employee. His job is to do what you ask him to do, and only what you ask him to do, otherwise you can show him the door. Always remember this. You are driving the boat, not him. You can try to not pay him, but that will be hard to do if you have a legal contract and there is nothing in it about leaving code as-is. But, you can simply let him go at any time.
Second, if you can't get him to stop and revert, and you can't get rid of him, you can tell him that if he plans to do style changes, then he should do all style changes in one check-in with absolutely NO code changes. This allows you to move forward from a base set of code that can be diffed to see code changes.
Third, make him explain the justification for the changes he's made. Removing var has no performance benefit.
Fourth, and this may suck a great deal, but youc an always use ReSharper to put the code back to your accepted style after the fact. It's more work, and you still have borked diffs, but oh well. The lambdas are harder, and that's the one you should really get on his case about.
Fifth, to drive home your point, force him to back out every change he's made and re-implement only the code changes, and not the style changes. That should open his eyes as to the mess he's created when he can't figure it out himself.
Finally, you may just have the bite the bullet and PAY him to revet back. Yes, it sucks, but since you made the mistake of not policing him, not specifying up front what you wanted, and what he's not allowed to do... You will pay the ultimate price. You can either pay him to do it, pay someone else to do it, pay you to do it, or live with it (and pay the price of the borked diffs). Any way you cut it, it will cost you money.

Well, smells like a solution wide code reformatting to me, that could be automated/enforced by settings in a tool like Resharper. I would think it very impolite and would ask him to refrain from pressing the "Reformat all code according to my personal taste" button.

To avoid the situation happening in the first place, introduce code review, particularly for any new developers joining who may not know your standards.
I'm a big fan of using git, feature branches and a service that supports pull requests (github or bitbucket). TFS isn't really up to the job, but thankfully Visual Studio supports git now. Doing code review before merging to master ensures it doesn't get forgotton. If you're paranoid you don't even need to give contractors write access to your primary repository.

Alternate point of view:
Your make two statements: "While the contractor has appeared to do a good job with the performance" and "they have also gone through large amounts of the code replacing the pre-existing style with their personal preference."
This raises many questions such as: Whenever you can "drop in" a contractor for a short period of time and gain performance enhancements. This indicates that there must have been very major flaws in the application in the first place. Anytime you need to bring in a contractor to "fix performance" this is a sign of very poorly written code or a very complex problem that requires high end expertise.
Next: When you complain that they have changed the code style even though you did not have any stated code style are you just making a pointless argument about your mojo being better than someone else's mojo. Maybe you should ask the person why they made changes which appear syntactical such that you have a complete picture.
I'm looking at the long list of one sided answers on this post and wondering what happened to the other side. Folks take the emotion out of it and look at it objectively. It's often amazing how many people will look past a beautiful algorithm solution to a complex problem just to notice that the variable naming convention has been altered from camel case to pascal case. I generally put this type of reaction down to justification of self worth by finding immaterial flaws.
Key question I have to ask is: Does the newly formatted code make the application any less readable. If you had budget constraints why did you not make it explicit that you wanted very specific fixes and nothing else. If you wanted to maintain a specific coding style then why not have that explicitly stated?

Related

Abstracting multiple C# classes

I have to deal with a project where someone else has copied and pasted the same class some 12 times, added some customization, but mainly, the structure of the classes are really similar because they were copied from each other.
I am itching to refactor the code because I can't stand looking at the code base.
Is there a tool that can automate some of this headache, that is, extract identical properties and methods into a parent class and make the other classes inherit from it?
Similar to arivman, give Resharper a shot. 30 day free trial, life-time license available per person (means can take it back home, and to other jobs if they'll allow it).
I don't know any free solution (other than doing it yourself), but you could give NET Refractor from KnowDotNet a shot. They even have a 30 day free trial!
I'd also recommend you to use a tool like Clone Detective before you opt for the Natural selection, there might be more hidden duplication.
Resharper squigglies will definitely give you some hints about code smells and keyboard combos to fix then in a jiffy.
You could also potentially use some bits and pieces from here and i personally find branching and tagging to be quite effective in situations like these. Any analytical due diligence prior to delving in the code i think goes a long way too.
Here we use simian to find the duplicate code. But again you still need manual intervention 2 remove or 2 update it.

Questions on Juval Lowy's IDesign C# Coding Standard [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
We are trying to use the IDesign C# Coding standard. Unfortunately, I found no comprehensive document to explain all the rules that it gives, and also his book does not always help.
Here are the open questions that remain for me (from chapter 2, Coding Practices):
No. 26: Avoid providing explicit values for enums unless they are integer powers of 2
No. 34: Always explicitly initialize an array of reference types using a for loop
No. 50: Avoid events as interface members
No. 52: Expose interfaces on class hierarchies
No. 73: Do not define method-specific constraints in interfaces
No. 74: Do not define constraints in delegates
Here's what I think about those:
I thought that providing explicit values would be especially useful when adding new enum members at a later point in time. If these members are added between other already existing members, I would provide explicit values to make sure the integer representation of existing members does not change.
No idea why I would want to do this. I'd say this totally depends on the logic of my program.
I see that there is alternative option of providing "Sink interfaces" (simply providing already all "OnXxxHappened" methods), but what is the reason to prefer one over the other?
Unsure what he means here: Could this mean "When implementing an interface explicitly in a non-sealed class, consider providing the implementation in a protected virtual method that can be overridden"? (see Programming .NET Components 2nd Edition, end of chapter “Interfaces and Class Hierarchies”).
I suppose this is about providing a "where" clause when using generics, but why is this bad on an interface?
I suppose this is about providing a "where" clause when using generics, but why is this bad on a delegate?
Ok so I will basically chip in with the little rep I have on stackoverflow: You can all kill me for opening a religious debate.
The hint to working with Juval's code standard is really in it's preface:
"I believe that while fully understanding every insight that goes into a particular programming decision may require reading books and even years of experience, applying the standard should not."
Next hint is to read his work.
Next would be doing what he advices.
Maybe on the way understand why he is recognised as a "microsoft software legend".
The next might be that it is delivered in a read-only pdf.
That didnt satisfy you?
The key here is realizing this is not a religious narrative, it is indeed a pragmatic one.
My personal experience with his standard is pretty much:
If you follow the advices as best you can, you will get a productive outcome.
Your needs of refactoring will be less, you productivity in the later cycles of the project will be higher.
This is an experience based evaluation.
Basically what you are looking for are the answers to "why" certain portions of the coding standard is in there, specifically these: 26, 34, 50, 52, 73, 74
You are asking these questions from a pragmatic perspective: You want to incorporate the standard and you "somehow" know this will give you a benefit in the longer run.
By examining these rules, through experience, you will perhaps come to understand why they are indeed there. Experience is here doing and not doing your code in accordance with the principles.
But really that isnt the point. The point is that by working from the basis of a well considered, mature and reliable standard, your work now becomes work of quality.
On how to follow a standard
Really read the rules as advices, they are already very strictly worded: "Avoid, do not, do and so on" really means what they say. Avoid means "think really hard before breaking the principle". "Do not" really means "do not".
Juval is all about decoupling and most of his harder-to-grok advices really comes from not thinking "separation" into your code design.
Sometimes this is hard to do with a team that works in less abstract terms or in more feature oriented environments, and you can therefore sometimes find it necessary to break rules, "to get the team moving", but you really should refactor this to the standard when you can do so.
After a few years, a few projects more, you perhaps will come to understand the rationale for each and every rule in the simple guide. If you are a bright student. Me, I'm not so bright, so I base it on experience: Stuff that is in the non-standardized parts of the code often fails during integration testing. It is often harder to come back to. It often ties poorly to the environment and so on.
It really is a matter of trust. If you cant find it in yourself to trust this (not adopt it - trust it), standard, I will propose to you that you will find it hard to ever really write comprehensible c# code that is generally of a acceptable quality.
This of course not considering the few really smart and really experienced out there that managed to build up their own set of internalizable rule sets on how to write code that is:
Stable, readable, maintainable, extendable and generally mega-ble.
This not saying that this is the only standard, just that it do indeed work. Also over time.
You will be able to find other standards, most if not all, though sub-standard to this for working with code you "really want to work" in the long run, involving a team of developers and changing real time situations.
So consider your standard, it is really setting the bar for the quality you provide for the $ you earn.
Do not reconsider it, unless you have "real good reasons to".
But do learn from it.
You reached here and you are still not satisfied. You want answers!
Darn it. Ok let me give you my clouded and sub-par experience based view on the rules your team can't grok.
No. 26: Avoid providing explicit values for enums unless they are integer powers of 2
Its about simplicity and working within that simplicity.
Enum's in c# are already numbered from "i=0" and injecting "++i" for every new field you define. The simplest way to [read code with/] think about enums are therefore either you flag them or you enumerate them.
When you dont do this, you are probably doing something wrong.
If you use the enum to "map" some other domain model, this rule can be broken, but the enum should be visibily separated from normal enums through placement/namespace/etc - to indicate you are "doing something not ordinary".
Now look at the enums you have created out-of-standard. Really look at them. Probably they are mapping something that really do not belong in a hard-coded enum at all. You wanted the efficiency of a switch, but you have in actuality now begun to hardcode out-of-domain properties. Sometimes this is ok and can be refactored later, sometimes it is not.
So avoid it.
The argument of "inserting into the middle" in the development process, is not really an issue that should break the standard. Why? Well if you are using or in any way storing the "int value" of the enumeration, then you are already diverging into a usage pattern where you need to stay very focused indeed. Not using 0, 1, 2 is not the answer to problems in that particular domain, i.e you are probably "doing it wrong".
The EF code-first argument is, probably not an issue to circumvent the rule here. If you feel you have such a need, please do describe your situation in a separate thread and I will try to guide you how to both follow the standard and work with your persistance framework.
My initial take would be: If they are code-first poco entities, then let them abide by the code standard, After all your team have decided to work with a code-first view on the data model. Allow them to do just that, following the same semantics as the rest of their code base.
If you run into specific problems related to the mapping to database tables, then solve these problems while maintaining the standard. For EF 4.3 I would say use the get/set with int pattern and replace in 5.0.
The real gritty stuff here is how to maintain this entity as the database evolves. Be sure to provide clear migration paths for your production database when your enum containing entities change design. Be very sure if the entities themselves change values. This go for add/remove/insert of new definitions. Not just add.
No. 34: Always explicitly initialize an array of reference types using a for loop
My guess is this is an "experience based" rule. In such a way that he looked through a lot of code and this point seemed to fail often for those that did not do it.
No. 50: Avoid events as interface members
Basically a question of separation - your interfaces are now coupled "both" ways into the interface and out of it. Read his book for clarification on why that is not "best practice" in the c# world.
In my limited view this is probably argumentation along the lines of: "Call-backs are very different in nature from function-calls. they make assumptions on the state of the receiver at an undefined "later time" of execution. If you want to provide callbacks, by all means do provide them, but make them into separate interfaces and also define an interface to negotiate these callbacks, in effect establishing all the hard things you wanted to abstract away, but really just circumvented. Or probably just use a recognized pattern. aka read the book."
No. 52: Expose interfaces on class hierarchies
Separation. I cant really explain it any further than: The alternative is hard to factor into a larger context/solution.
No. 73: Do not define method-specific constraints in interfaces
Separation. same as #52
No. 74: Do not define constraints in delegates
Separation.
Conclusion
......
Another view on #50 is that it is one of those rules where:
If you dont get it, its probably not important for you.
Importance here is an estimate on how critical the code is - and how critically you want that code to always work as intended.
This again leads into a broader context on how to verify your code actually is quality.
Some would say this can be done with tests only.
They however fail to understand the interconnectedness between defensively writing quality software and aggressively trying to prove it wrong.
In the real world, those two should be parts of a greater totality with the actual requirements of the software being the third.
Doing a quick mock-up? who cares. Doing a little visual thingy that you understand the runtime constraints of? who cares - well probably you should, but perhaps acceptable. and so on.
In the end compliance to a coding standard is not something you take on lightly.
There are reasons for doing it that goes beyond just the code:
Collaboration and communication primarily.
Agreement on shared views.
Assertions of assumptions.
etc.
No. 26: Power of two means you want to use the enum as a bitmask (flags). Thats the only reason to specify enum values. For adding new members later on, you can still append them to the enum definition without changing existing values. No reason to put them between existing members.
No. 34: I think he wants to avoid the situation where you have an array wich contains (partially) uninitialized pointers (null references). As the consumer of an array its tempting
not to check for null entries in a valid array variable.
No. 26: He's quite wrong, at least for public enums. The problem crops up when you remove an item, not when you add one (for which adding to the end of the list would be equivalent to adding an item with the next available value).
For the others, I'm really not sure why he's making these recommendations, although I have to admit that I find a few (or maybe most) of them rather dubious...

How do I show that I'm getting the smallest number of conflicts with Git by using K&R instead of B&D as the coding standard?

Git is smart and will "follow" changes in history to make merging easier and auto merge more for me. Conflicts are delineated by the lines that have not changed around the change. With K&R you get no ambiguous lines that have only "{" in them like you would in B&D. How would I test the limit of the context sensitivity that Git has in terms of the lines that surround a change?
I want to avoid resolving conflicts that I may not need to. But I need some way to test how many potential conflicts I will save by switching to K&R and the additional context it brings.
So far, Git is too smart to get fooled by trivial examples.
Any help is appreciated. Thanks in advance.
So this is the closest thing I have found so far as evidence to this.
http://git.661346.n2.nabble.com/Bram-Cohen-speaks-up-about-patience-diff-td2277041.html
The e-mail is discussing the purpose of the "patience" algorithm in Git. In it Bram explains how superfluous matching lines can create nasty conflicts that can be tough to resolve but only in the case of fairly complex merges involving large patches. In other words simple contrived examples will fail to show this behavior.
While he does also mention things like End affecting the results it makes some sense to infer that placing an opening brace on it's own line increases the number of superfluous matching lines possibly resulting in a greater probability of these conflicts.
I'd say this isn't iron-clad, but it does lend some credence to this theory.
So 'unique lines' is a simple cross-language proxy for 'unimportant
lines'.
That quote stands out to me in this discussion, since we are basically matching on what we feel are important lines that are supposed to give us context, however a brace by itself is not important and provides no context.
Pick standard that is easier for you/your team to read over anything else. No matter how your source control system behaves today it will behave better tomorrow, but your code will stay the way you've checked it in for long time.
We have several large projects (over 200+ code files), which contain a massive mixture of both K&R AND B&D. I can safely say that after almost 2 years on Git, a development staff that is refactoring-crazy, and a rebasing behavior of "several time a day", that I have never had a conflict due to coding standards things. So pick whichever, or both, or neither. It won't matter.

Verifying license information without a boolean check? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I'm currently using a simple XML file that contains license information along with the data's signature and public key. So far, this method is working great. However, I'm seeing one rather large security flaw...
When my ASP.NET MVC application starts, it verifies the license and sets the "ValidLicense" bool property accordingly. During each request, this property is checked and an error message is displayed if the license is invalid.
As you can guess, there's absolutely nothing to stop a competent user from simply modifying my assembly to set "ValidLicense" to true regardless of the license's validity. I know this can be done to pretty much any application, but it seems incredibly easy to do with .NET assemblies.
What are some ways that I can stop this from happening, or at least make it a little more difficult to crack the license verification procedure?
I'd rather stay away from assembly encryption and obfuscation systems, if possible. Go ahead and suggest them if you feel that they are good enough to warrant the cost and extra headache, however.
The only way to win is not to play.
The people who are going to steal your stuff (regardless of what protections you put in place), are not the people who are going to pay for it if it's too hard for them to break.
Instead of a simple boolean variable, you could perform a complex calculation every time you need to verify the license and base your logic on the result from that calculation. You do get a perf hit, though. And cracking your assembly wouldn't be that much harder anyway.
You could also employ some more advanced techniques, like dynamic mutation of the code and using the a corresponding mutable function to control the flow of your logic.
However, you should ask yourself does your assembly really contain such precious intelectual property, as to warrant the time and efforts to implement anything like this? It might be more viable and cheaper to go the legal route and battle the potential piracy if and when it occurs.
You can make it a bit more complicated but in the end it will come down to one (or several) booleans: Either you run the code or you don't. Non-obfuscated.NET code is pretty much the same as open source and it is ridiculously easy to crack open.
Even if obfuscation is not a full solution, I think it would make sense to obfuscate, just to prevent fringe amateurs from producing cracked versions.
Of course it won't stop a real cracker who is willing to spend the time, but just by putting the bar a little higher, you can weed out a lot of crackers wannabes.
Obfuscation can be pretty simple to implement for free. If you have a commercial version of Visual Studio, you can use DotFuscator (not with the "Express" editions). I never tried, but I guess it should be simple enough.
Otherwise, you can use Assemblur. (http://www.metapropeller.com/). The free version is a command line application (there is a GUI to create the setting file, but you need to run the settings from the command line).
All in all, it barely takes a couple minutes to obfuscate a simple exe file and it's free
If you want to make your license check a little more challenging, you can make different checks inside various methods, and you can also make sure that the license checking code does not actually output any string directly. (for instance, you do a license check in method A, but you output the error warning from method B, so that when a cracker looks for the license error message, he doesn't land right on the bit of code to be changed).
All it does is raise the bar for wannabe crackers and make things more complex for a real cracker.
Case 1: Non obfuscated .NET application with 1 license check method which output a "not licensed" error message.
Can be cracked in about 5 minutes by anyone who can run reflector.
Case 2: Obfuscated .NET application with a couple different license checks and no obvious string output.
Could take hours for a cracker and prove too hard for a wannabe.
You can get from case 1 to case 2 with about 1 hour of work, without spending a dime. Going beyond that is probably a waste of time (everything can be cracked) but at least, you can weed out the folks who open your application in Reflector just to see if it's going to be easy. If the guy opens the application in reflector and sees something like:
public bool ValidateLicense(string sLicense)
{
string sInvalidLicense = "Your license is not valid";
...
}
Guess what happens next?
//EDIT: In a comment, LC asked:
How do you not have it output any string message but still notify the user? Even if you do a license check and output in two different methods, you'll still have a the binary decision "if(!ValidateLicense(LicenseCode)) {NotifyUserOfInvalidLicense(); throw new LicenseException();}" or something, no?
Put yourself in the shoes of a cracker: You are looking for the License validation code. You are not going to study the whole code just to find it. Instead, you run the application unlicensed: The error message shows up.
You take that error message, you open the assembly in Refactor and you search for a part of that error message.
If that string is located inside "ValidateLicence()", you immediately find the ValidateLicence() function. From there, you only need to locate the return value and change that 1 byte. Done.
If the string is found instead inside "WhatEver()", you still needs to find what methods call "WhatEver()". It might not even be in the same assembly (in which case Refactor will not find it for you). This makes the job harder for your wannabe cracker. He will have to look at that method to see how it validates the code (which it doesn't). He might even be sloppy and change the return value of the wrong method, in which case he introduces a bug (if the method is obfuscated, figuring out what it does is not that simple).
Better yet, don't use a string at all: you can store the error message as a sequence of hex codes, and convert it to string dynamically when you need to display the message. No error string means that the cracker will have to rely on something else to locate your license validation code. And reading through obfuscated code is not fun.
You could also have a fake validation method containing the error message and suppress the warning to make it look like the crack worked.
So, a couple of simple, stupid tricks like these + simple obfuscation are very easy to implement and they can turn a 5 minutes "In and Out" cracking session into weeks of work for the cracker, because not only does he need to find and crack your validation code, but he also has to test to make sure that everything is working and that he didn't just fix a decoy or unwillingly created nasty bugs. Now, he just can't be sure without testing.
In the end, cracking an assembly is just a matter of changing a few bytes, and you can't prevent anyone from changing bytes in your assembly's files. Everything can be cracked.
However you can make it a hell of a lot harder to find which bytes have to be changed, and at the very least, you can avoid having a string that says "the byte you are looking for is right here".
An approach I met when trying to hack a little .NET product was to use an unmanaged .DLL for the licence checking. And not only that, the .DLL also contained a lot of code that was actually used in the software. So, to crack product I actually had to crack the unmanaged .DLL (or make a perfect wrapper). Needless to say, this stopped a wannabe cracker like me. :)

In C# (or any language) what is/are your favourite way of removing repetition?

I've just coded a 700 line class. Awful. I hang my head in shame. It's as opposite to DRY as a British summer.
It's full of cut and paste with minor tweaks here and there. This makes it's a prime candidate for refactoring. Before I embark on this, I'd thought I'd ask when you have lots of repetition, what are the first refactoring opportunities you look for?
For the record, mine are probably using:
Generic classes and methods
Method overloading/chaining.
What are yours?
I like to start refactoring when I need to, rather than the first opportunity that I get. You might say this is somewhat of an agile approach to refactoring. When do I feel I need to? Usually when I feel that the ugly parts of my codes are starting to spread. I think ugliness is okay as long as they are contained, but the moment when they start having the urge to spread, that's when you need to take care of business.
The techniques you use for refactoring should start with the simplest. I would strongly recommand Martin Fowler's book. Combining common code into functions, removing unneeded variables, and other simple techniques gets you a lot of mileage. For list operations, I prefer using functional programming idioms. That is to say, I use internal iterators, map, filter and reduce(in python speak, there are corresponding things in ruby, lisp and haskell) whenever I can, this makes code a lot shorter and more self-contained.
#region
I made a 1,000 line class only one line with it!
In all seriousness, the best way to avoid repetition is the things covered in your list, as well as fully utilizing polymorphism, examine your class and discover what would best be done in a base class, and how different components of it can be broken away a subclasses.
Sometimes by the time you "complete functionality" using copy and paste code, you've come to a point that it is maimed and mangled enough that any attempt at refactoring will actually take much, much longer than refactoring it at the point where it was obvious.
In my personal experience my favorite "way of removing repetition" has been the "Extract Method" functionality of Resharper (although this is also available in vanilla Visual Studio).
Many times I would see repeated code (some legacy app I'm maintaining) not as whole methods but in chunks within completely separate methods. That gives a perfect opportunity to turn those chunks into methods.
Monster classes also tend to reveal that they contain more than one functionality. That in turn becomes an opportunity to separate each distinct functionality into its own (hopefully smaller) class.
I have to reiterate that doing all of these is not a pleasurable experience at all (for me), so I really would rather do it right while it's a small ball of mud, rather than let the big ball of mud roll and then try to fix that.
First of all, I would recommend refactoring much sooner than when you are done with the first version of the class. Anytime you see duplication, eliminate it ASAP. This may take a little longer initially, but I think the results end up being a lot cleaner, and it helps you rethink your code as you go to ensure you are doing things right.
As for my favorite way of removing duplication.... Closures, especially in my favorite language (Ruby). They tend to be a really concise way of taking 2 pieces of code and merging the similarities. Of course (like any "best practice" or tip), this can not be blindly done... I just find them really fun to use when I can use them.
One of the things I do, is try to make small and simple methods that I can see on a single page in my editor (visual studio).
I've learnt from experience that making code simple makes it easier for the compiler to optimise it. The larger the method, the harder the compiler has to work!
I've also recently seen a problem where large methods have caused a memory leak. Basically I had a loop very much like the following:
while (true)
{
var smallObject = WaitForSomethingToTurnUp();
var largeObject = DoSomethingWithSmallObject();
}
I was finding that my application was keeping a large amount of data in memory because even though 'largeObject' wasn't in scope until smallObject returned something, the garbage collector could still see it.
I easily solved this by moving the 'DoSomethingWithSmallObject()' and other associated code to another method.
Also, if you make small methods, your reuse within a class will become significantly higher. I generally try to make sure that none of my methods look like any others!
Hope this helps.
Nick
"cut and paste with minor tweaks here and there" is the kind of code repetition I usually solve with an entirely non-exotic approach- Take the similar chunk of code, extract it out to a seperate method. The little bit that is different in every instance of that block of code, change that to a parameter.
There's also some easy techniques for removing repetitive-looking if/else if and switch blocks, courtesy of Scott Hanselman:
http://www.hanselman.com/blog/CategoryView.aspx?category=Source+Code&page=2
I might go something like this:
Create custom (private) types for data structures and put all the related logic in there. Dictionary<string, List<int>> etc.
Make inner functions or properties that guarantee behaviour. If you’re continually checking conditions from a publically accessible property then create an private getter method with all of the checking baked in.
Split methods apart that have too much going on. If you can’t put something succinct into the or give it a good name, then start breaking the function apart until the code is (even if these “child” functions aren’t used anywhere else).
If all else fails, slap a [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] on it and comment why.

Categories