I acknowledge that they can be useful, but I'm trying to wrap my head around when I would actually want to have a func as a parameter of a method.
public void WeirdMethod(int myNumber, func op);
In terms of design and functionality, could someone explain to me some circumstances where I would want to consider this? Theories of "reusability" isn't going going to help me much. Real world scenarios would be best. Help me think like you lol.
Here's about all I know:
This would allow me to pass a delegate
This would allow me to use a lambda expression.
Yeap...
NOTE:
I know this thread will get closed since there's no "right" answer. But I think what clicked it for me just now was "delayed calculation".
Deferring operations until a later time. A very practical example is deferring change tracking until an object tree is fully populated. Each type or repository can tell you what it wants done, and the caller can decide when to actually do it.
Composition of logic (as Justin Niessner mentioned).
Abstraction, e.g. ("here's a contract that has inputs and ouputs, but I don't care what it's implementation is as long as it fulfills the contract). For example, you could pass a "statusWriter" Func to a method which might write to a console, debug window, log file, database, or do nothing at all. All the consuming method knows is that it consumes a type and invokes it when desired.
Along the same lines, passing a Func to a method allows an abstracted and simple way of allowing a where predicate to be defined by the caller. I use this paradigm frequently to support a strongly-typed filter to be applied to a result (not talking about LINQ to SQL, just filtering a list of information as the caller sees fit).
Elegant functional paradigms, such as this example which demonstrates recursion using anonymous functions. These constructs would be verbose/impossible without the ability to pass one function to another (especially in an abbreviated form).
A general scenario is when you must pass a delayed calculation to your method. This is useful when calculating something is expensive, for example, when you cache something.
public Guid GetFromCache(string key, Func<Guid> make) {
Guid res;
if (!cache.TryGetValue(key, out res)) {
res = make();
cache.Add(key, res);
}
return res;
}
Now you can call this method as follows:
Guid guid = GetFromCache(myKey, () => database.MakeNewGuid());
If you had something asynchronous and you wanted to give it a callback method?
They enable to you to Curry functions as well as use Functional Composition.
While you've almost certainly used delegates before (since that's what events are), LINQ is a prime example for when passing a delegate as a function parameter is useful.
Think about Where. You're supplying a piece of logic (specifically a definition of what meets your criteria--whatever they are) to a function that uses it as part of its execution.
Related
I am a student and I am currently preparing for my OOP Basics Exam.
When in the controller you have methods which return a value and such that are void - how do you invoke them without using a if-else statement?
In my code "status" is the only one which should return a string to be printed on the Console - the others are void. So I put a if-esle and 2 methods in the CommandHandler.
Since I know "if-else" is a code smell, is there a more High Quality approach to deal with the situation?
if (commandName == "status")
{
this.Writer.WriteLine(this.CommandHandler.ExecuteStatusCommand(commandName));
}
else
{
this.CommandHandler.ExecuteCommand(commandName, commandParameters);
}
This is the project.
Thank you very much.
First, don't worry about if/else. If anybody tells you if/else is a code smell, put it through the Translator: What comes out is he's telling you he's too crazy, clueless, and/or fanatical to be taken seriously.
If by ill chance you get an instructor who requires you to say the Earth is flat to get an A, sure, tell him the Earth is flat. But if you're planning on a career or even a hobby as a navigator, don't ever forget that it's actually round.
So. It sounds to me like CommandHandler.ExecuteStatusCommand() executes the named command, which is implemented as a method somewhere. If the command method is void, ExecuteStatusCommand() returns null. Otherwise, the command method may return a string, in which case you want to write it to what looks like a stream.
OK, so one approach here is to say "A command is implemented via a method that takes a parameter and returns either null or a string representing a status. If it returns anything but null, write that to the stream".
This is standard stuff: You're defining a "contract". It's not at all inappropriate for command methods which actually return nothing to have a String return type, because they're fulfilling the terms of contract. "Return a string" is an option that's open to all commands; some take advantage, some don't.
This allows knowledge of the command's internals to be limited to the command method itself, which is a huge advantage. You don't need to worry about special cases at the point where you call the methods. The code below doesn't need to know which commands return a status and which don't. The commands themselves are given a means to communicate that information back to the caller, so only they need to know. It's incredibly beneficial to have a design which allows different parts of your code not to care about the details of other parts. Clean "interfaces" like this make that possible. The calling code gets simpler and stays simpler. Less code, with less need to change it over time, means less effort and fewer bugs.
As you noted, if you've got a "status" command that prints a result, and then later on you add a "print" command that also prints a result, you've got to not only implement the print command itself, but you've also got to remember to return to this part of your code and add a special case branch to the if/else.
That kind of tedious error-prone PITA is exactly the kind of nonsense OOP is meant to eliminate. If a new feature can be added without making a single edit to existing code, that's a sort of Platonic ideal of OOP.
So if ExecuteCommand() returns void, we'll want to be calling ExecuteStatusCommand() instead. I'm guessing at some things here. It would have been helpful if you had sketched out the semantics of those two methods.
var result = this.CommandHandler.ExecuteCommand(commandName, commandParameters);
if (result != null)
{
this.Writer.WriteLine(result);
}
If my assumptions about your design are accurate, that's the whole deal. commandParameters, like the status result, are an optional part of the contract. There's nothing inherently wrong with if/else, but sometimes you don't need one.
I have a custom MVC framework in which I'm overhauling the routing API. I'm trying to think of a clean way to segregate "setup" and "execution" in my framework which makes extensive use of delegates and generics. Right now I envision this from the calling side:
//setup
MyRouter.AddRoute("/foo", () => new MyHandler(), (h) => h.MyMethod);
//h.MyMethod only exists in MyHandler, not in HttpHandler
//execution
MyRouter.Execute(HttpContext);
I can make the AddRoute method signature "work" currently:
delegate T HandlerInvoker<T>();
delegate string HandlerCallMethod<T>(T handler);
...
public void AddRoute<T>(string pattern, HandlerInvoker<T> invoker, HandlerCallMethod<T> caller) where T is HttpHandler{...}
If I didn't need to store the invoker and caller and could do it all right then, this would work fine. But, I do need to store the invoker and caller to later execute.
Current things I've thought about doing:
Storing them in a List<object> and then using reflection to call them. This seems extremely complicated and probably not too good of performance
Moving AddRoute to execution. This can make it harder for people using my API, but might end up being my only "good" choice
Ask a SO question :)
Is there any good way of storing these generic types without a ton of painful reflection?
You could store an anonymous delegate that performs all the conversion for you.
It looks like the following would work (not tested in any way):
List<Action> handlers;
handlers.Add(() => caller(invoker()));
Note that this wouldn't work if you were caching invoker.
In that case you need to make preserve the value, Lazy should do the trick.
List<Action> handlers;
Lazy<T> lazy = new Lazy<T>(invoker);
handlers.Add(() => caller(lazy.Value);
That latter will only create one instance of the return value of invoker per call to the method. And since lazy is a local variable, it is automatically shoved into a class which is held onto as long as handlers holds onto a reference for you.
Note that I ignored pattern, but it seems you don't need any help there.
When writing an API or reusable object, is there any technical reason why all method calls that return 'void' shouldn't just return 'this' (*this in C++)?
For example, using the string class, we can do this kind of thing:
string input= ...;
string.Join(input.TrimStart().TrimEnd().Split("|"), "-");
but we can't do this:
string.Join(input.TrimStart().TrimEnd().Split("|").Reverse(), "-");
..because Array.Reverse() returns void.
There are many other examples where an API has lots of void-returning operations, so code ends up looking like:
api.Method1();
api.Method2();
api.Method3();
..but it would be perfectly possible to write:
api.Method1().Method2().Method3()
..if the API designer had allowed this.
Is there a technical reason for following this route? Or is it just a style thing, to indicate mutability/new object?
(x-ref Stylistic question concerning returning void)
EPILOGUE
I've accepted Luvieere's answer as I think this best represents the intention/design, but it seems there are popular API examples out there that deviate from this :
In C++ cout << setprecision(..) << number << setwidth(..) << othernumber; seems to alter the cout object in order to modify the next datum inserted.
In .NET, Stack.Pop() and Queue.Dequeue() both return an item but change the collection too.
Props to ChrisW and others for getting detailed on the actual performance costs.
Methods that return void state more clearly that they have side effects. The ones that return the modified result are supposed to have no side effects, including modifying the original input. Making a method return void implies that it changes its input or some other internal state of the API.
If you had Reverse() return a string, then it wouldn't be obvious to a user of the API whether it returned a new string or the same-one, reversed in-place.
string my_string = "hello";
string your_string = my_string.reverse(); // is my_string reversed or not?
That is why, for instance, in Python, list.sort() returns None; it distinguishes the in-place sort from sorted(my_list).
Is there a technical reason for following this route?
One of the C++ design guidelines is "don't pay for features you don't use"; returning this would have some (slight) performance penalty, for a feature which many people (I, for one) wouldn't be inclined to make use of.
The technical principal that many others have mentioned (that void emphasizes the fact the function has a side-effect) is known as Command-Query Separation.
While there are pros and cons to this principle, e.g., (subjectively) clearer intent vs. more concise API, the most important part is to be consistent.
I'd imagine one reason might be simplicity. Quite simply, an API should generally be as minimal as possible. It should be clear with every aspect of it, what it is for.
If I see a function that returns void, I know that the return type is not important. Whatever the function does, it doesn't return anything for me to work with.
If a function returns something non-void, I have to stop and wonder why. What is this object that might be returned? Why is it returned? Can I assume that this is always returned, or will it sometimes be null? Or an entirely different object? And so on.
In a third-party API, I'd prefer if that kind of questions just never arise.
If the function doesn't need to return anything, it shouldn't return anything.
If you intend your API to be called from F#, please do return void unless you're convinced that this particular method call is going to be chained with another nearly every time it's used.
If you don't care about making your API easy to use from F#, you can stop reading here.
F# is more strict than C# in certain areas - it wants you to be explicit about whether you're calling a method in order to get a value, or purely for its side-effects. As a result, calling a method for its side-effects when that method also returns a value becomes awkward, because the returned value has to be explicitly ignored in order to avoid compiler errors. This makes "fluent interfaces" somewhat awkward to use from F#, which has its own superior syntax for chaining a series of calls together.
For example, suppose we have a logging system with a Log method that returns this to allow for some sort of method chaining:
let add x y =
Logger.Log(String.Format("Adding {0} and {1}", x, y)) // #1
x + y // #2
In F#, because line #1 is a method call that returns a value, and we're not doing anything with that value, the add function is considered to take two values and return that Logger instance. However, line #2 not only also returns a value, it appears after what F# considers to be the "return" statement for the function, effectively making two "return" statements. This will cause a compiler error, and we need to explicitly ignore the return value of the Log method to avoid this error, so that our add method has only a single return statement.
let add x y =
Logger.Log(String.Format("Adding {0} and {1}", x, y)) |> ignore
x + y
As you might guess, making lots of "Fluent API" calls that are mainly about side-effects becomes a somewhat frustrating exercise in sprinkling lots of ignore statements all over the place.
You can, of course, have the best of both worlds and please both C# and F# developers by providing both a fluent API and an F# module for working with your code. But if you're not going to do that, and you intend your API for public consumption, please think twice before returning this from every single method.
Besides the design reasons, there is also a slight performance cost (both in speed and space) for returning this.
This pattern pops up a lot. It looks like a very verbose way to move what would otherwise be separate named methods into a single method and then distinguished by a parameter.
Is there any good reason to have this pattern over just having two methods Method1() and Method2() ? The real kicker is that this pattern tends to be invoked only with constants at runtime-- i.e. the arguments are all known before compiling is done.
public enum Commands
{
Method1,
Method2
}
public void ClientCode()
{
//Always invoked with constants! Never user input.
RunCommands(Commands.Method1);
RunCommands(Commands.Method2);
}
public void RunCommands(Commands currentCommand)
{
switch (currentCommand)
{
case Commands.Method1:
// Stuff happens
break;
case Commands.Method2:
// Other stuff happens
break;
default:
throw new ArgumentOutOfRangeException("currentCommand");
}
}
To an OO programmer, this looks horrible.
The switch and enum would need synchronised maintenance and the default case seems like make-work.
The OO programmer would substitute an object with named methods: Then the names like method1 would only appear once in the library. Also all the default cases would be obviated.
Yes, your clients still need to be synchronised with the methods you supply - a static language always insists on method names being known at compile time.
You could argue that this pattern allows you to put shared logging (or other) code for method entry and exit in a single place. But I wouldn't. AOP is a better approach for this sort of thing.
That pattern could be valid if you needed the coupling to be very loose. For example you might have an interface
interface CommandProcessor{
void process(Command c);
}
If you have a method per command then each time you add a new command you would need to add a new method, if you have multiple implementations then you would need to add the method to each Processor. This could be resolved by having some base class, but if the needs diverge you could end up with a very deep class heirarchy as you add new abstraction layers (or you may already be extending another class in with the processor. If it is based on switch's over the constant you can have you default case that handles new cases appropriately by default (exceptions, whatever may be appropriate).
I have used a pattern similar to this in my code with the addition of a factory. The operations started as a small set, but I knew they would be increasing, so I had a mechanism to describe the command and then a factory that produced CommandProcessors. The factory would generate the appropriate processor and then the single method of that processor would accept the command and perform its processing.
That said if your list of command is fairly static and you don't need to worry about how tightly things are coupled then the one-method-per-command approach certainly lends itself to much more readable code.
I can't see any obvious advantages. Quite the opposite; by splitting the blocks into separate methods, each method will be smaller, easier to read and easier to test.
If needed, you could still have the same "entry point" method, where each case would just branch out and call another method. Whether that would be a good or bad idea is impossible to say without knowing more about specific cases. Either way, I would definitely avoid implementing the code for each case in the RunCommands method.
If RunCommands is only ever invoked with the names constants, then I don't see any advantage in this pattern at all.
The only advantage I see (and it could be a big one) would be that the decision between Method1 and Method2 and the code that actually executes the choice could be entirely unrelated. Of course that advantage is lost, when only constants are ever used to invoke RunCommand.
if the code being run inside each case block is completely separate, no value added. however, if there is any common code to be executed before or after the parameter-specific code, this allows it to not be repeated.
still not really the best pattern, though. each separate method could just have calls to helper methods to handle the common code. and if there needs to be another call, but this one doesn't need the common code in front or at the end, the whole model is broken (or you surround that code with and IF). at this point, all value is lost.
so, really, the answer is no.
I'm always looking for a way to use all the tools I can and to stretch myself just beyond where I am at. But as much as I have read about delegates, I can never find a place to use them (like Interfaces, Generics, and a lot of stuff, but I digress.) I was hoping someone could show me when and how they used a delegate in web programming for asp.net c#(2.0 and above).
Thank you and if this wrong for Stack Overflow, please just let me know.
bdukes is right about events. But you're not limited to just using delegates with events.
Study the classic Observer Pattern for more examples on using delegates. Some text on the pattern points toward an event model, but from a raw learning perspective, you don't have to use events.
One thing to remember: A delegate is just another type that can be used & passed around similar to your primitive types such as an "int". And just like "int", a delegate has it's own special characteristics that you can act on in your coding when you consume the delegate type.
To get a really great handle on the subject and on some of it's more advanced and detailed aspects, get Joe Duffy's book, .NET Framework 2.0.
Well, whenever you handle an event, you're using a delegate.
To answer your second question first, I think this is a great question for StackOverflow!
On the first, one example would be sorting. The Sort() method on List takes a delegate to do the sorting, as does the Find() method. I'm not a huge fan of sorting in the database, so I like to use Sort() on my result sets. After all, the order of a list is much more of a UI issue (typically) than a business rule issue.
Edit: I've added my reasons for sorting outside the DB to the appropriate question here.
Edit: The comparison function used in the sort routine is a delegate. Therefore, if you sort a List using the .Sort(Comparison(T)) method the Comparison(T) method you pass to the sort function is a delegate. See the .Sort(Comparison(T)) documentation.
Another quick example off the top of my head would be unit testing with Rhino Mocks. A lot of the things you can do with Rhino Mocks utilize delegates and lambda expressions.
You can use delegates whenever you know you will want to take some action, but the details of that action will depend on circumstances.
Among other things, we use delegates for:
Sorting and filtering, especially if the user can choose between different sorting/filtering criteria
Simplifying code. For example, a longish process where the beginning and end are always the same, but a small middle bit varies. Instead of having a hard-to-read if block in the middle, I have one method for the whole process, and pass in a delegate (Action) for the middle bit.
I have a very useful ToString method in my presentation layer which converts a collection of anything into a comma-separated list. The method parameters are an IEnumerable and a Func delegate for turning each T in the collection into a string. It works equally well for stringing together Users by their FirstName or for listing Projects by their ID.
There isn't anything special to asp.net related to delegates (besides considerations when using async stuff, which is a whole different question), so I will point you to other questions instead:
Delegate Usage : Business Applications
Where do I use delegates?
Another example would be to publish events for user controls.
Eg.
// In your user control
public delegate void evtSomething(SomeData oYourData);
public event evtSomething OnSomething;
// In the page using your user control
ucYourUserControl.OnSomething += ucYourUserControl_OnSomething;
// Then implement the function
protected void ucYourUserControl_OnSelect(SomeData oYourData)
{
...
}
Recently i used the delegates for "delegating" the checking of the permissions.
public Func CheckPermission;
This way, the CheckPermission function can be shared by various controls or classes, say it in a static class or a utilities class, and still be managed centralized, avoiding also Interface explossion; just a thought