class my_class
{
public int add_1(int a, int b) {return a + b;}
public func<int, int, int> add_2 = (a, b) => {return a + b;}
}
add_1 is a function whereas add_2 is a delegate. However in this context delegates can forfill a similar role.
Due to precedent and the design of the language the default choice for C# methods should be functions.
However both approaches have pros and cons so I’ve produced a list. Are there any more advanteges or disadvantages to either approach?
Advantages to conventional methods.
- more conventional
- outside users of the function see named parameters – for the add_2 syntax arg_n and a type is generally not enough information.
- works better with intellisense – ty Minitech
- works with reflection – ty Minitech
- works with inheritance – ty Eric Lippert
- has a “this” – ty CodeInChaos
- lower overheads, speed and memory – ty Minitech and CodeInChaos
- don’t need to think about public\private in respect to both changing and using the function. – ty CodeInChaos
- less dynamic, less is permitted that is not known at compile time – ty CodeInChaos
Advantages to “field of delegate type” methods.
- more consistant, not member functions and data members, it’s just all just data members.
- can outwardly look and behave like a variable.
- storing it in a container works well.
- multiple classes could use the same function as if it were each ones member function, this would be very generic, concise and have good code reuse.
- straightforward to use anywhere, for example as a local function.
- presumably works well when passed around with garbage collection.
- more dynamic, less must be known at compile time, for example there could be functions that configure the behaviour of objects at run time.
- as if encapsulating it’s code, can be combined and reworked, msdn.microsoft.com/en-us/library/ms173175%28v=vs.80%29.aspx
- outside users of the function see unnamed parameters – sometimes this is helpfull although it would be nice to be able to name them.
- can be more compact, in this simple example for example the return could be removed, if there were one parameter the brackets could also be removed.
- roll you’r own behaviours like inheritance – ty Eric Lippert
- other considerations such as functional, modular, distributed, (code writing, testing or reasoning about code) etc…
Please don’t vote to close, thats happened already and it got reopened. It’s a valid question even if either you don’t think the delegates approach has much practical use given how it conflicts with established coding style or you don’t like the advanteges of delegates.
First off, the “high order bit” for me with regards to this design decision would be that I would never do this sort of thing with a public field/method. At the very least I would use a property, and probably not even that.
For private fields, I use this pattern fairly frequently, usually like this:
and now I can very easily test the performance characteristics of different memoization strategies without having to change the text of ActualFunction at all.
Another advantage of the “methods are fields of delegate type” strategy is that you can implement code sharing techniques that are different than the ones we’ve “baked in” to the language. A protected field of delegate type is essentially a virtual method, but more flexible. Derived classes can replace it with whatever they want, and you have emulated a regular virtual method. But you could build custom inheritence mechanisms; if you really like prototype inheritance, for example, you could have a convention that if the field is null, then a method on some prototypical instance is called instead, and so on.
A major disadvantage of the methods-are-fields-of-delegate-type approach is that of course, overloading no longer works. Fields must be unique in name; methods merely must be unique in signature. Also, you don’t get generic fields the way that we get generic methods, so method type inference stops working.