|
I assume that he meant to say that he's glad to take some time off in a glade.
If you have an important point to make, don't try to be subtle or clever. Use a pile driver. Hit the point once. Then come back and hit it again. Then hit it a third time - a tremendous whack.
--Winston Churchill
|
|
|
|
|
It could be worse. You could be coding in Limericks .
"When you don't know what you're doing it's best to do it quickly" - Jase #DuckDynasty
|
|
|
|
|
That's something I always wanted to do, many moons ago when I was working in COBOL, where you could actually set it up to have sections of code as poems, but I never had enough time free to apply myself to it.
Shame. It would be nice to know that somewhere in a bank there was a little bit of soul.
I wanna be a eunuchs developer! Pass me a bread knife!
|
|
|
|
|
I know just the place[^] you can visit to enjoy your time off!
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
I made a mental connection of Glade with Raid and thought it was a pun. (Bug reports) Maybe I need some time off as well!
"Go forth into the source" - Neal Morse
|
|
|
|
|
It gets worse. We're replying in verse.
|
|
|
|
|
I won't do that.
I'll sound like a prat.
I wanna be a eunuchs developer! Pass me a bread knife!
|
|
|
|
|
Glade, in the UK, is a spray for masking nasty smells.
I don't think I want to know where you're going to be sitting for the next few few days, but my advice is drink plenty of lightly salted water, and eat lots of bananas.
I wanna be a eunuchs developer! Pass me a bread knife!
|
|
|
|
|
Sorry to burst your bubble but that's not a Limerick.
|
|
|
|
|
* DISCLAIMER *
This isn't a programming question, because I've solved the programming problem myself.
Rather, I'm interested in your opinion regarding the solution, clever or 'clever'?
So today I had a nice little challenge.
My application has a grid which can be sorted on various columns, asc and desc.
Now the sorting isn't applied by clicking the column header, but by selecting a value from a drop down (Name, Name (descending), Title, Title (descending) etc.).
I was thinking I could just have a switch statement where I check which ordering the user chose (which would make me extend the switch for each new ordering), or... I could abstract this away.
Of course I went for the second option. Now to make this work (and it works nicely, adding a new ordering is a piece of cake) I had to write the following function:
SomeFunction(string caption, Func<IQueryable<TElement>, Expression<Func<TElement, TKey>>, IQueryable<TElement>> linqFunction, Expression<Func<TElement, TKey>> expression) { ... } Since this is a WinForms application though, and WinForms and generics don't go well together I'm more or less forced to use a dynamic later on as it's quite impossible to get the values of TElement and TKey from object .
I'm thinking this isn't ideal in terms of complexity and readability, but it is pretty neat because adding a new ordering is really simple (one line of simple code) and guaranteed to work on the first try (you'll never forget to change that switch statement again).
And the solution is even re-usable for the filter functionality I need as well (which, of course, becomes a breeze as well)!
So judging from that, clever or 'clever'?
And where do you draw the line for cleverness vs. readability/simplicity?
|
|
|
|
|
I can't read that code.
Do you actually sort the grid? Or sort the data that is then displayed by the grid? A standard DataGridView generally displays a DataView (based on a DataTable) and you control the sorting with the Sort property.
Does your solution allow multi-level sorting? E.g. first by X, then by Y ? I can't stand grids that allow sorting on only one column at a time .
I'm unclear on the details of what you have, but I would consider having each Item in the DropDown know what it is supposed to do -- perhaps a class with a Name and a Delegate -- so all you need do is add a new Item to the DropDown.
|
|
|
|
|
I'm sorting the data that is then displayed by the grid. The DataGridView works pretty well when you have a DataView, but all I'm having is a List<T> which I haven't been able to sort in the past if my life depended on it. So it's easier to just take your original list, sort it (using OrderBy and OrderByDescending) and bind to the result. The same goes for filtering with Where.
PIEBALDconsult wrote: Does your solution allow multi-level sorting? Nope, should be a new value in the drop down, like "name then title".
PIEBALDconsult wrote: I'm unclear on the details of what you have, but I would consider having each Item in the DropDown know what it is supposed to do -- perhaps a class with a Name and a Delegate -- so all you need do is add a new Item to the DropDown. That's exactly what I have
The code I posted above could be called as follows:
comboBoxOrdering.Items.Add(SomeFunction("Name", Queryable.OrderBy, q => q.Name)); I need all the generics so my IntelliSense (and compiler) knows that q is actually some type that has a Name property
And I'm having something similar for the filter functionality (which is also a dropdown).
comboBoxFilters.Items.Add(SomeFunction("Active only", Queryable.Where, q => q.Active)); So even if you couldn't read the code above, I'm pretty sure you could use it
|
|
|
|
|
Sander Rossel wrote: That's exactly what I have
Oh. Well, alright then.
|
|
|
|
|
A shame you didn't recognize it. It's an indication that my code is, indeed, 'clever'... Not sure how to make it more readable though (I guess this is the part where it becomes a programming question ).
|
|
|
|
|
Have you considered adding a comment? I find that's generally a good idea for clever code (with or without quotes).
|
|
|
|
|
It's funny you should say that.
While you certainly make a valid point allow me to explain why I don't think that's the solution.
If the code is so unclear it needs comments I really think you should stop and have another look at your code.
Try rewriting it so that it shouldn't need comments (which is what I did).
If there's really nothing else you can do you can use a comment, but I highly discourage it.
I've said it before and I'll say it now; comments are the evil of this world
In fact I've had so much bad experiences with comments that I've written a tip about it a few years ago.
If you're interested: Write comments that matter[^].
Thanks for the tip though
|
|
|
|
|
Sander Rossel wrote: And where do you draw the line for cleverness vs. readability/simplicity? The latter would be considered clever. Anyone can write complex code, but it is hard to reduce complexity to smaller and simpeler tasks.
Sander Rossel wrote: I was thinking I could just have a switch statement where I check which ordering
the user chose (which would make me extend the switch for each new ordering), I'd be using inheritance to do so. Requires a complete class if you want another switch option. I'd be doing the same for the columns; write a single column and inherit from there, and simply call "sort" on the column.
If it works, then it works. If everyone in your team accepts it, keep it.
I would recommend to create a special class (yes, another) to keep all the arguments you're passing to the method. That way you'd pass a specialized object instead of a (rather lengty) parameter-list. Has the added advantage (besides the obvious readability) that you can loop your arguments using reflection, log them if desired, and inherit them when creating a newer version. Similar to the EventArgs principle
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Eddy Vluggen wrote: I'd be using inheritance to do so. Requires a complete class if you want another switch option. Actually, what you're looking at is the constructor of that function
Eddy Vluggen wrote: I'd be doing the same for the columns; write a single column and inherit from there, and simply call "sort" on the column Have you ever worked with the WinForms DataGridView? It's a beast and if you're going to inherit anything from it you're in for a rough ride
Eddy Vluggen wrote: I would recommend to create a special class (yes, another) to keep all the arguments you're passing to the method. It already is, but what's the difference between having a function that takes these arguments or a constructor that takes them? Or did you want to pass them to the class someway else?
Fun fact, in my code you're mostly looking at the signature of common LINQ functions like OrderBy and Where
|
|
|
|
|
Sander Rossel wrote: Actually, what you're looking at is the constructor of that function
The fact that you have to explain that is an indication of the readability.
Sander Rossel wrote: Have you ever worked with the WinForms DataGridView? Yes, and I love it. Cannot say the same for the XtraGrid or the MSFlexGrid. Which would you recommend, if not the DataGridView?
Sander Rossel wrote: It already is, but what's the difference between having a function that takes
these arguments or a constructor that takes them? It would work the same for a constructor as well as a method; it is a simply way of reducing the amount of arguments.
public static Process Start(
ProcessStartInfo startInfo
) That's a factory-method, with a single argument. I think that is a bit more readable than having all the options listed. There's another advantage in this idea if you're planning to inherit the Process-class; your inherited class could easily extend the parameter list without changing the method-signature.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Eddy Vluggen wrote: The fact that you have to explain that is an indication of the readability. Actually, I shouldn't have called it SomeFunction Eddy Vluggen wrote: Which would you recommend, if not the DataGridView? Definitely XtraGrid, all sorting and filtering capabilities you need right out of the box!. Sure, steep learning curve, but it's worth it
Eddy Vluggen wrote: That's a factory-method, with a single argument. But somewhere there's a class constructor for ProcessStartInfo that has all those parameters, right?
|
|
|
|
|
Sander Rossel wrote: Actually, I shouldn't have called it SomeFunction I admit I have used the prefix "some" in production code.
Sander Rossel wrote: Definitely XtraGrid, all sorting and filtering capabilities you need right out
of the box!. Sure, steep learning curve, but it's worth it I keep hearing that, yet personally I keep preferring speed and simplicity.
Sander Rossel wrote: But somewhere there's a class constructor for ProcessStartInfo that has all
those parameters, right? Check for yourself[^].
You'd probably not need them ALL at once, so it would make no sense to provide an overload that lists them all as real arguments. I also do not see any benefit in the extra overload, only a higher LOC - you'd loose aforementioned benefits that bundlig the arguments has. If they are part of the method-signature, then it will be harder to log (instead of simply serializing the arguments-object), and the signature would change if a parameter needs to be added.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Eddy Vluggen wrote: You'd probably not need them ALL at once True for the ProcessStartInfo, but my method only has three and I always need all of them.
I can see how such a class would make sense though (I probably don't use it far enough).
Eddy Vluggen wrote: I admit I have used the prefix "some" in production code. I'll pretend I didn't see that!
|
|
|
|
|
Sander Rossel wrote: I'm thinking this isn't ideal in terms of complexity and readability, IMO any generic solution beats writing endless switch-statements or having to update code in multiple places when introducing a new field or whatever. Even if it's bordering on your personal definition of complexity and readability. The other solution probably wouldn't win a prize either
Sander Rossel wrote: I'm more or less forced to use a dynamic later on as it's quite impossible to get the values of TElement and TKey from object . Can you elaborate?
|
|
|
|
|
Sascha Lefévre wrote: Can you elaborate? Sure.
Consider this
MyClass<SomeClass, string> result = SomeFunction("Name", Queryable.OrderBy, q => q.Name);
comboBox.Items.Add(result);
comboBox.Items.Add(SomeFunction("Date", Queryable.OrderBy, q => q.Date));
comboBox.Items.Add(SomeFunction("Age", Queryable.OrderBy, q => q.Age));
object ordering = comboBox.SelectedItem;
MyClass<SomeClass, ...?> result = (MyClass<SomeClass, ...?>)ordering;
dynamic ordering = comboBox.SelectedItem;
ordering.LinqFunction(ordering.Predicate);
|
|
|
|
|
Makes sense. But is there a specific reason why you didn't use a signature like this:
MyClass<SomeClass> ordering = SomeFunction(string caption, Func<IQueryable<TElement>, IQueryable<TElement>> applyPredicate) { ... }
And then use it like this:
comboBox.Items.Add(SomeFunction("Date", source => source.OrderBy(q => q.Date)));
MyClass<SomeClass> ordering = (MyClass<SomeClass>)comboBox.SelectedItem;
ordering.ApplyPredicate();
|
|
|
|
|