A previous developer placed a static string called "Qry" in a "god" class in a project I inherited.
The developer then used this static variable in every single place throughout the program that a single db query string is built and used.
For instance:
SomeGodClass.Qry = "select count(1) from AddressBook where Name = '" + txtName.Text.Trim(' ') +
"' and Group_Name = '" + txtGroupName.Text.Trim(' ') + "'";
int count = sqlHelper.ExecuteScalar(SomeGodClass.Qry);
Thus, this variable is referenced exactly 626 times, most with a different query being assigned. There are other static variables like this that he used - probably 50 of them - but this is the most predominant.
My first instinct is to remove this static string and rework all 626 usages. However, I don't know if this is a bad enough practice to take the time to do it.
Thus, my question is: Is this an acceptable use of a static string, especially when taking into consideration the amount of work refactoring would take?
Don't see any problem of using static here, at least judging from the code I see. But do not use TextBox concatenation !
Use Parameters instead.
That is most important refactoring I can think of while looking on the code provided.
Why do we always prefer using parameters in SQL statements?
You should definitely refactor this. It looks like SomeGodClass.Qry was ment to be a constant of some kind, but what good is a constant if you keep reassigning it? Now you never know what's its value, unless you have just overwritten it.
Just use a local variable query instead, and use parameters (like Tigran said)
One of the main issues with using a static member for code like this is that at first glance, it looks fine (if a little redundant).
SomeGodClass.Qry = /* Some Query */;
int count = sqlHelper.ExecuteScalar(SomeGodClass.Qry);
It assigns a value, then uses it, great. The problem comes if you start introducing threads into your application. Suddenly, the static is being assigned and used from multiple threads and there's no guarantee that the value used in the Execute is the same one that was assigned higher up the method.
How big an issue this is, obviously depends on your application, if the code's in a library etc...
Related
I have built an abstract class that is used to handle command line options for our products.
One need only to create a class inheriting from AbstractOptions, fill it with decorated fields and call the inherited Parse(args) method to have it automatically filled through reflection with values from the command line. Values that were not found on the command line retain their current (default) values.
Then, the application needs only to check the option fields to get their value. The AbstractOptions class provides more features, like help output, etc, but it is beside the point.
Short example:
public class SignalOptions: AbstractOptions
{
[Option("-i, --iterations", "Number of iterations (0 = infinite).")]
volatile public int NumberOfIterations;
[Option("-s, --silent", "Silent mode, only display final results.")]
volatile public bool Silent;
[Option("-w, --zwindow", "Window size for z-score analysis.")]
volatile public int ZWindow = 7;
[Option("-a, --zalert", "z-score value to consider as peak.")]
public double ZAlert = 2.1;
}
static void Main(string[] args)
{
var opts = new SignalOptions();
opts.Parse(args)
// If optimizations are turned off, SILENT will be written or not
// followind presence or absence of the --silent switch on the command line.
// If optimizations are turned on, SILENT will never be written.
// The reflection part is working fine. I suspect the problem is that
// the compiler of the jitter having never found this set anywhere simply inlines
// the value 'false' inthe if, because when I step on it, it shows me the value as
// true or false, but has the same behavior no matter what value opts.Silence has.
if( opts.Silent )
Console.Writeline("SILENT");
}
Now, the problem I have is that since the compiler does not find any code actually changing the values of the SignalOptions class, it simply inlines the values where they are used in the code. I have circumvent the issue by requiring that all 'option' fields in the class be volatile, so no optimization is applied, and it works fine, but unfortunately the volatile keyword is not valid on a double.
I have spent much time on the net trying to find a workaround, without success. Is there anyway to either prevent optimizations on the fields or otherwise fool the compiler/jitter into thinking they are used at runtime?
I also would like to put as less as possible the onus on the calling application.
Thanks
I have a local copy here with Parse written as the rather opaque:
public void Parse(string[] args)
{ // deliberately opaque, not that it would make any difference
string fieldName = (new string('S', 1) + "ilentX").Substring(0, 6);
GetType().GetField(fieldName).SetValue(this, true);
}
It works fine. I do not believe the problem is what you think it is.
Here is my guess:
Parse is running in a separate thread, but as your synchronization is somehow flawed, this makes the rest of code run without having the values set already.
This would also explain why you are seeing the correct values in the debugger.
Update (opinionated):
Having Parse run in a separate thread is very weird, and should be considered a design flaw. Sounds like someone was thinking 'Reflection is slow, let's put it in a separate thread'.
If I need to do something like this:
var connection = new Connection(host);
connection.Execute(Commands.Delete);
Is there anything wrong in doing this:
(new Connection(host)).Execute(Commands.Delete);
The first example may be more readable, but the second works better if I need to do this multiple times:
(new Connection(anotherHost)).Execute(Commands.Create);
(new Connection(someOtherHost)).Execute(Commands.Update);
(new Connection(host)).Execute(Commands.Delete);
Does your Connection class implement IDisposable? Then:
using (var connection = new Connection(host))
{
connection.Execute(Commands.Delete);
}
First thing I am a Java person and I havent used C#
But based on your code and knowing similarity with java what I can say is -
If your Connection class maintains a state information then its meaningful to create new object every time. But if it is stateless then its pretty inefficient to create multiple objects. You can create one and re-use the same.
i.e. If you cannot set the 'host' to a connection once created, then both approaches you mentioned should not make any difference.
The more verbose you are, the easier of a time you will have debugging.
The effect on your code readability really depends on how much you're trying to wrap into one line - if you've got a single idea that just takes a lot of different words to express, putting it in one line isn't a big deal in my opinion. But if you're trying to cram multiple ideas into one line you'll lose clarity.
For instance. We'll start with a simple idea that just takes some space to express:
transactionTime = generationTime + retrievalTime + processingTime + loggingTime
And here we have a more complex idea that we happen to express in one line:
logTransactionData(processTransaction(retrieveTransaction(generateTransactionQuery())))
I think that the first example is easier to understand at a glance than the second, even though they're about the same in character length.
So in general: consider how likely it is you'll need to debug the line, as well as your idea-complexity-to-line ratio.
Yes, you're initializing a new object, using it, and loosing it! you cannot reuse it again and it's gonna be there somewhere, until GC collects it! So, there's no harm in storing new initialized objects in a variable, and declaring them in another line makes your code more readable.
The example below may not be problematic as is, but it should be enough to illustrate a point. Imagine that there is a lot more work than trimming going on.
public string Thingy
{
set
{
// I guess we can throw a null reference exception here on null.
value = value.Trim(); // Well, imagine that there is so much processing to do
this.thingy = value; // That this.thingy = value.Trim() would not fit on one line
...
So, if the assignment has to take two lines, then I either have to abusereuse the parameter, or create a temporary variable. I am not a big fan of temporary variables. On the other hand, I am not a fan of convoluted code. I did not include an example where a function is involved, but I am sure you can imagine it. One concern I have is if a function accepted a string and the parameter was "abused", and then someone changed the signature to ref in both places - this ought to mess things up, but ... who would knowingly make such a change if it already worked without a ref? Seems like it is their responsibility in this case. If I mess with the value of value, am I doing something non-trivial under the hood? If you think that both approaches are acceptable, then which do you prefer and why?
Thanks.
Edit: Here is what I mean when I say I am not a fan of temp variables. I do not like code like this:
string userName = userBox.Text;
if (userName.Length < 5) {
MessageBox.Show("The user name " + userName + " that you entered is too short.");
....
Again, this may not be the best way to communicate a problem to the user, but it is just an illustration. The variable userName is unnecessary in my strong opinion in this case. I am not always against temporary variables, but when their use is very limited and they do not save that much typing, I strongly prefer not to use them.
First off, it's not a big deal.
But I would introduce a temp variable here. It costs nothing and is less prone to errors. Imagine someone has to maintain the code later. Better if value only has 1 meaning and purpose.
And don't call it temp, call it cleanedValue or something.
It is a good practice not to change the values of incoming parameters, even if you technically can. Don't touch the value.
I am not a big fan of temporary variables.
Well, programming is largely about creating temporary variables all over the place, reading and assigning values. You'd better start to love them. :)
One more remark regarding properties. Although you could technically put a lot of logic there, it is recommended to keep properties simple and try not to use any code that could throw exceptions. A need to call other functions may indicate that this property is better be made a method or that there is some initialization code needed somewhere. Just rethink what you're doing and whether it does really look like a property.
I often find myself using lambdas as some sort of "local functions" to make my life easier with repetetive operations like those:
Func<string, string> GetText = (resource) => this.resourceManager.GetString(resource);
Func<float, object, string> FormatF1 = (f, o) => String.Format("{0:F1} {1}", f, o);
Func<float, object, string> FormatF2 = (f, o) => String.Format("{0:F2} {1}", f, o);
Instead of writing the String.Format-thing over and over, I can happily blow away with FormatF2 e.g. and save myself time and when I need to change something about the formatting, only one place to make edits.
Especially when I need the functionality in the given function exclusively, I'm very reluctant to turn them into a real function. While the lambdas above were relatively small... sometimes I have larger ones like (the following is supposed to add data to a table for print output):
Action<string, string, string> AddSurfaceData = (resource, col, unit) => {
renderTable.Cells[tableRowIndex, 0].Text = "\t" + this.GetText(resource);
renderTable.Cells[tableRowIndex, 1].Text = FormatF2(paraHydReader.GetFloat(paraHydReader.GetOrdinal(col)), "");
renderTable.Cells[tableRowIndex, 1].Style.TextAlignHorz = C1.C1Preview.AlignHorzEnum.Right;
renderTable.Cells[tableRowIndex, 2].Text = " " + this.GetText(unit);
renderTable.Cells[tableRowIndex, 2].Style.TextAlignHorz = C1.C1Preview.AlignHorzEnum.Left;
++tableRowIndex;
};
Again, I need this often and all the benefits of above apply, too. However, as you can see, this one is quite long for a lambda expression.. the question is: When do you draw the line? Is my last lambda too much? What other ways (other than using real functions or trying to stuff the data in containers and loop over them) exist to avoid writing the same code over and over again?
Thanks in advance
Christian
It is something you use potentially many times within a method, and only that inside that method. I like this idea. Do it if it doesn't make your code hard to read. I would say that you should reconsider if you find it difficult to see what is the content of the lambda function vs. what is the real content of the method. In that case it might be cleaner to pull it out in a separate private method.
At the end, this is really a matter of taste...
I agree with awe: for small scale reuse inside a method (or even a class) this is perfect. Like the string.Format examples. I use this quite often. It's basically the same thing as using a local variable for an intermediate value that you use more than once, but then for code.
Your second example seems to be pushing it a bit. Somehow this gives me the feeling a private method AddSurfaceData (possibly static, depending on its use?) would be a better fit. That is of course outside of the context that you have, so use your own good judgement.
A Lambda method is an anonymous method.
This means that you should not give it a name.
If you are doing that, (in your case, you are assigning a name with your reference), it's just another way to declare a function.
C# has already got a way to declare functions, and it's not the lambda way, which was added
uniquely to pass functions via parameters and returns them as return values.
Think, as an example, in javascript:
function f(var1,var2,...,varX)
{
some code
}
or
var f = function() {
some code
}
Different syntax (almost) same thing.
For more information on why it's not the same thing: Javascript: var functionName = function() {} vs function functionName() {}
Another example: in Haskell You can define two functions:
function1 :: Int -> Int
function1 x = x + 2
or
function2 :: Int -> Int
function2 = \x -> x + 2
Same thing (this time I think it's the very same), different syntax. I prefer the first one, it's more clear.
C# 3.5, as Javascript, has got a lot of functional influences. Some of them should it be used wisely, IMHO.
Someone said local lambda functions with assignment in a reference is a good substitute for a method defined within another method, similar to a "let", or a "where" clause in Haskell.
I say "similar" because the twos have very different semantics, for instance, in Haskell I can use function name which is not declared yet and define it later with "where", while in C#, with function/reference assignment I can't do this.
By the way I think it's a good idea, I'm not banning this use of lambda function, I just want to make people think about it.
Every language has got his abstraction mechanism, use it wisely.
I like the idea. I don't see a better way to maintain code locality without violating the DRY principle. And I think it's only harder to read if you're not accustomed to lambdas.
+1 on nikie re DRY being good in general.
I wouldnt use PascalCase naming for them though.
Be careful though - in most cases the stuff you have in there is just an Extract Method in a dress or a potential helper or extension function. e.g., GetText is a Method and FormatF* is probably a helper method...
I have no problem with the long example. I see that you are repackaging compound data very elegantly.
It's the short ones that will drive your colleagues to investigate the advantages of voluntary institutionalization. Please declare some kind of constant to hold your format string and use "that String.Format-thing over and over". As a C# programmer, I know what that does without looking elsewhere for home-spun functions. That way, when I need to know what the formatted string will look like, I can just examine the constant.
I agree with volothamp in general, but in addition ...
Think of the other people that have to maintain your code. I think this is easier to understand than your first example and still offers the maintenance benefits you mention:
String.Format(this.resourceManager.GetString("BasicFormat"), f, o);
String.Format(this.resourceManager.GetString("AdvancedFormat"), f, o);
And your second example appears to be just a different way to declare a function. I don't see any useful benefit over declaring a helper method. And declaring a helper method will be more understandable to the majority of coders.
I personally think its not in good taste to use lambda functions when there is no need for it. I personally wont use a lambda function to replace a simple few lines of procedural code. Lambda functions offer many enhancements, but make the code slightly more complicated to read.
I wouldnt use it to replace string.format.
I'm wondering if this is good, bad?
SelectRecipientResponse user = SomeUtil.SelectRecipient(p.Email, p.ListID.ToString());
bool userIsInList = user.ExistsInList;
bool userIsOptedOut = user.IsOptedOut;
user = null;
user = SomeUtil.SelectRecipient(p.Email, _masterSuppressionListID);
bool userIsInSupressionList = user.ExistsInList;
so I'm using one instance of user to check to see if they are in 2 lists. Lists I am checking are over a 3rd party API. I want to do one check, null out that object and reuse it again.
Does this seem typical? I'm just trying to code this smartly so wanted to see what one thinks about this technique above.
This is fine because you aren't reusing the object, you are simply reusing the local variable that holds the reference to the object.
That being said, I personally feel that it would be better to simply create a second variable to hold the second reference as I find that more readable.
Actually, you're using the same variable, i.e. the name user, to refer (in separate zones of your code) to (possibly-)separate instances of SelectRecipientResponse, since each call to SelectRecipient is (or may well be) returning a distinct one. No big problem with that. And no need to set user explicitly to null before reassigning it, either.
You're asking for trouble when some other developer comes back in a year and starts working with user further down in the method not noticing that you overwrote it with a second assignment. Name your variable what it is. This would probably qualify as unnecessary premature optimization.
It's completely acceptable to re-assign variables, though there is absolutely no legitimate reason to assign null to the variable, then assign it to something else.
In terms of readability, when I am re-using local variables, I don't generally assign it on the first declaration.
I'll typically write:
SqlParameter param;
param = new SqlParameter(...);
param.Value = "";
... // and again
param = new SqlParameter(...);
param.Value = "";
In this way, it's kind of clear that it's being re-used (or at least re-assigned). Works for me, anyway, and it means that I can happily re-order things (if it becomes relevant) without too much trouble.