tag:blogger.com,1999:blog-15136575.post3349887079083667752..comments2023-10-17T12:00:16.772+01:00Comments on Code rant: C#: Program Entirely With Static MethodsMike Hadlowhttp://www.blogger.com/profile/16441901713967254504noreply@blogger.comBlogger47125tag:blogger.com,1999:blog-15136575.post-26583881381363325032018-12-31T19:11:25.301+00:002018-12-31T19:11:25.301+00:00This is very helpful because I find myself slowly ...This is very helpful because I find myself slowly converging on the same pattern. I often write classes with one or two dependencies, and they tend to be small and stateless. The dependencies themselves also often have one method. (I've recently leaned toward injecting delegates instead of interfaces, partially for that reason.) So the pattern you demonstrated of replacing the class with a method and replacing the injected dependency with an argument is perfect.<br /><br />Going a step further, when I inject a dependency I tend to use only one method. So the next logical step is for the method to take a delegate as an argument instead of an interface or class.<br /><br />One thing I like about this approach is that it makes it more difficult for someone to clutter the code. They can't sneak in new class dependencies by adding new members to existing interfaces. <br />Scott Hannenhttps://www.blogger.com/profile/16535488279436639196noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-38614179419523131592018-05-24T14:37:41.289+01:002018-05-24T14:37:41.289+01:00Nice write up. Far easier to maintain Functional a...Nice write up. Far easier to maintain Functional and Procedural code vs OOP. The advantages of OOP have been exaggerated for years. Let's face facts regarding time, money, manpower, budgets. The code is built once and maintained for years. Good Code all ways ends up being about about EASE of maintenance. Functional and Procedural coding is making a comeback for good reason. Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-15136575.post-44306335495172218532017-08-03T20:40:28.555+01:002017-08-03T20:40:28.555+01:00Action and func are just templates for delegates. ...Action and func are just templates for delegates. A delegate is effectively a method signature and analogous to an interface with a single method. So i'd be inclined to agree with using delegates over action/function as it is more expressive. This article is thought provoking which is great and static methods should offer performance improvements to some extent but f# immutable types offers thread safety which hasn't even entered this discussion. Great article.Anonymoushttps://www.blogger.com/profile/13016361725848284535noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-27855646500195954462017-04-13T19:11:23.946+01:002017-04-13T19:11:23.946+01:00C# 7 Named tuples can solve the Action problem.
...C# 7 Named tuples can solve the Action problem.<br /><br /> class Program<br /> {<br /> static void Main()<br /> {<br /> RunCustomerReportBatch(SendEmail);<br /><br /> Console.ReadKey();<br /> }<br /> public static void SendEmail((string toAddress, string body) emailFields)<br /> {<br /> // pretend to send an email here<br /> Console.Out.WriteLine("Sent Email to: {0}, Body: '{1}'", emailFields.toAddress, emailFields.body);<br /> }<br /><br /> public static void RunCustomerReportBatch(Action<(string toAddress, string body)> sendEmail)<br /> {<br /> //....code omitted for breviety<br /><br /> sendEmail(("Recipient@test.com", "Test Report Body"));<br /> }<br /> }Jason Bowershttps://www.linkedin.com/in/jcbowers/noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-81820613283034447552016-08-22T13:13:18.973+01:002016-08-22T13:13:18.973+01:00@Ricardo (http://mikehadlow.blogspot.de/2015/08/c-...@Ricardo (http://mikehadlow.blogspot.de/2015/08/c-program-entirely-with-static-methods.html?showComment=1438960380464#c1143071256575253270)<br /><br />I'd use delegates for that. They are like interfaces, but for methods, and c# can match them easily to lambda expressions or static methods.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-15136575.post-52599351744273632812016-07-20T19:37:34.607+01:002016-07-20T19:37:34.607+01:00Interesting. How does this play in a real world mv...Interesting. How does this play in a real world mvc app, using a container like StructureMap or AutoFac?Anonymoushttps://www.blogger.com/profile/00194759656218194020noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-23568642391302488402016-06-03T01:01:20.469+01:002016-06-03T01:01:20.469+01:00My career has followed a similar trajectory. I wa...My career has followed a similar trajectory. I was all on board with OO in C#, until one day the fancy features of F# aroused my curiosity. I spent many months diving head first into that language in my off time, and I found that I didn't care half so much about its fancy features as I did the style and paradigm of the language. Following that, my C# code has never been the same.<br /><br />I was recently asked to join a new, multi-division project, and I brought my functional style with me. I was expecting some push back, but much to my surprise, I have been showered with praise. Brilliant, masterpiece, top gun coder, etc are all being tossed around. No, functional programming is brilliant, and one can do some genuinely brilliant things with it. I just use the stuff.<br /><br />There are a couple dinosaurs in the project, but rest assured that I will convert them. The level of code reduction, readability, and stability gained is so immense--the productivity so enhanced--they will not be able to resist forever. And to any dinosaurs out there reading this comment, you will be assimilated. Resistance is futile.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-15136575.post-76254042579256853642016-05-21T08:28:27.853+01:002016-05-21T08:28:27.853+01:00Just found this post and have to agree. Over the p...Just found this post and have to agree. Over the past few years I have been moving more into the functional space with C#. As for does it scale, I can answer yes. I work on a project that is about a decade old so parts are in all flavors of C# from V2 onward. Most of the new stuff has been functional and it is cleaner, more consice and far easier to refactor because of it.<br /><br />The more I use functional the more I believe OO is a dead end and a productivity time suck. It simply does not give the fluidity of code that functional provides.<br /><br />Just look at your old code, if you have interfaces that have one method the question should be why, just a bunch of pointless noise. An interface, a class and possibly IOC registration and resolution. <br /><br />People used to worry about readonly dictionaries in C# but I just pass around a Func which is the lookup and also means you are not even tied to a dictionary.<br /><br />Functional, because you break everything down more, gives more building block with finer granularity and closures provide far more power and flexibility that classes can. <br /><br />So the current project has 500000 lines of C# and I can work faster and move faster in the functional stuff than I can in the OO Anonymoushttps://www.blogger.com/profile/18103195373576008490noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-67811207907246646562016-02-09T21:25:33.041+00:002016-02-09T21:25:33.041+00:00What is Abstract Data type?What is Abstract Data type?Muhammad Shumailhttps://www.blogger.com/profile/06170328187096773971noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-66992872694318422732015-11-05T20:29:01.386+00:002015-11-05T20:29:01.386+00:00Interfaces having one method doesn't stop you ...Interfaces having one method doesn't stop you grouping your code into classes or modules :) "rantings of a mad man" seems a little presumptive!James Morcomhttps://www.blogger.com/profile/11883160014225775464noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-49814042468558037692015-11-05T19:38:00.956+00:002015-11-05T19:38:00.956+00:00@James, seriously? You group code in classes and i...@James, seriously? You group code in classes and interfaces in OOP, you group code in modules in FP. Please don't bring forward the rantings of a mad man in the discussion - or accept that code that does something (accessing db (fetch/store), going to external providers etc. will end up with 8+ dependencies with that kind of thinking. And carrying around 8+ function pointer arguments will make your code brittle and confusing to say the least.<br />Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-15136575.post-72067177721039756172015-11-02T12:43:22.226+00:002015-11-02T12:43:22.226+00:00@Anonymous, when you're thinking functionally ...@Anonymous, when you're thinking functionally like this your interfaces all tend to end up with one method anyway: http://blog.ploeh.dk/2014/03/10/solid-the-next-step-is-functional/James Morcomhttps://www.blogger.com/profile/11883160014225775464noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-66869609681036523242015-11-01T20:15:00.711+00:002015-11-01T20:15:00.711+00:00Looks interesting. Can you please do a followup po...Looks interesting. Can you please do a followup post where your interfaces have say 3-4 methods each? I'm not really sure how your approach scale, hence why I'd like your take on a more realistic situation.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-15136575.post-21743749720756726982015-09-23T14:16:55.930+01:002015-09-23T14:16:55.930+01:00I like the approach even though it might lead to b...I like the approach even though it might lead to big overloads of constructors, specially when the injected dependencies were quite considerably in size (methods).<br /><br />Thanks for sharing :)Mauriciohttps://www.blogger.com/profile/13794090470662879298noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-974693054632006702015-09-10T16:15:56.548+01:002015-09-10T16:15:56.548+01:00@Harry McIntyre
Their loss. I often use explicit ...@Harry McIntyre<br /><br />Their loss. I often use explicit delegates to remove ambiguity. i.e:<br /><br />public delegate DateTimeOffset Now();<br /><br />instead of: Func<br /><br />I think there is something to be said about the clarity? Not just for people either. You can register that with you container and inject date time, or substitute easily in a test.Ed Blackburnhttps://www.blogger.com/profile/17045008823330793876noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-69065730721564286562015-09-10T16:14:54.598+01:002015-09-10T16:14:54.598+01:00This comment has been removed by the author.Ed Blackburnhttps://www.blogger.com/profile/17045008823330793876noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-46920039485670529792015-09-10T15:47:59.401+01:002015-09-10T15:47:59.401+01:00@Thomas Eyde
Using named delegates to make it exp...@Thomas Eyde<br /><br />Using named delegates to make it explicit what a Function is for can be harmful to your career - I recently received the following feedback from an offline coding test I had to submit when going for a contract (which I didn't get).<br /><br />"When using Funcs<> from 3.5 I would expect not to use delages cira 2.0 mixing these sort of stuff is a red flag for me. would expect to use Actions instead of delegates"<br /><br />Sigh.<br />Harry McIntyrehttps://www.blogger.com/profile/16748782353710296964noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-73718030517440418882015-09-08T09:59:17.816+01:002015-09-08T09:59:17.816+01:00I don't agree with the "complex mocking f...I don't agree with the "complex mocking framework" part. There's no added complexity to the first test as in additional abstraction layers, messy conditional logic or dirty technical tricks. Of course the mocking framework brings new vocabulary to the equation, but the semantics of "setting up" a context for the system under test and "verifying" stuff are naturally lurking in the test between the lines anyway, you might as well make them explicit. <br /><br />So to me the two implementations are equally readable, with the OO version maybe a little more intention-revealing thanks to "Verify( a method was called...)" and "Setup". But sure, you could be exactly as expressive in the functional version with some well-named helper functions.<br /><br />Anyway, a very good article about the functional approach to dependencies and testing.Unknownhttps://www.blogger.com/profile/16262097274511865267noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-31428690551515928682015-08-11T10:16:41.591+01:002015-08-11T10:16:41.591+01:00Nice article, I like the point.
This is a journey...Nice article, I like the point.<br /><br />This is a journey I've been on for a long time. Initially, bastardizing an OO language to work functionally feels like a nice thing to do. <br /><br />And then you realize that you are writing little functions everywhere to glue things together (like your compose function). <br /><br />So, you write a library of little combinators, such as the ones given in the answer to http://stackoverflow.com/questions/5264060/does-c-sharp-support-function-composition.<br /><br />You then realize that you could combine things so much better if you had partial application. And then you write some more little combinators. <br /><br />So much boiler-plate. When will it end? <br /><br />Then one day, the new person joins the team and they immediately spew as they see the crazy. You slowly open your eyes and realize that you can't put lipstick on a pig; C# ain't functional.<br /><br />My point is you can't turn a language into something it's not. C# is a great language, but it lacks some vital pieces to be an effective functional language (partial application is probably the biggest for me, but there's many more). Functional-esque C# is just a gateway drug to a functional language.<br />Jeffhttps://www.blogger.com/profile/08195722595923882332noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-73227992552464633352015-08-11T10:04:35.767+01:002015-08-11T10:04:35.767+01:00This comment has been removed by the author.Anonymoushttps://www.blogger.com/profile/15562343407613769990noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-50285659503280475042015-08-11T10:03:03.543+01:002015-08-11T10:03:03.543+01:00* "what if": what if this needs to chang...* "what if": what if this needs to change in the future.Anonymoushttps://www.blogger.com/profile/15562343407613769990noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-52585703295029732602015-08-11T09:59:20.285+01:002015-08-11T09:59:20.285+01:00If you had an INotifier with an email implementati...If you had an INotifier with an email implementation and something else, a truly needed encapsulation for data storage (other than a database? EF itself already is an abstraction), and more than one type of reporting services, I'd go with all the interface and all. <br /><br />To be very straight to the point: I see a lot of code with interfaces that are realized by only one type of object and it's useless. Many people code with the "what if" syndrome and that's waste of time.<br /><br />I would guess Mike's point here is simplicity. I liked the article.Anonymoushttps://www.blogger.com/profile/15562343407613769990noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-37977903488819703362015-08-10T17:52:44.212+01:002015-08-10T17:52:44.212+01:00I was going to complain about how bad and pointles...I was going to complain about how bad and pointless the interfaces were in your starting code but then realized it's a great example of real world. Totally pointless interfaces that offer nothing and don't need to exist.<br /><br /><br />@Ricardo Rodrigues the purpose of TypeScript isn't to make javascript less functional the purpose is to fix the insanity of how bad it is at handling contracts. It also adds meta programming (which some/all is being absorbed by ES6 because of the major lacking of it in JS)Chris Marisichttps://www.blogger.com/profile/08904925342941324684noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-88890353515399627492015-08-10T17:04:24.885+01:002015-08-10T17:04:24.885+01:00Did you do any performance profiling you can share...Did you do any performance profiling you can share? I'm interested in the runtime behavior of such conversions; lots of discussion of functional variants either ignore performance or the functional version is slower due to increased (hidden) looping and memory related to functional collection related thinking.<br /><br />I've enjoyed the recent tech du jour focus on functional languages, but I also am suspicious there's a reason why they have been around forever (i.e. Lisp in 1958) but always just a niche. Performance seems to be one thing keeping it there.Quadkohttps://www.blogger.com/profile/04247299096841479603noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-30356332954022857802015-08-10T16:38:47.758+01:002015-08-10T16:38:47.758+01:00If one's not doing it right it's fairly ea...If one's not doing it right it's fairly easy to achieve duplication but small interfaces doesn't mean low cohesion at all, exactly the opposite! It does one thing and it's very portable.<br /><br />When it does too many things, then you break cohesion (violating the <a href="https://en.wikipedia.org/wiki/Interface_segregation_principle" rel="nofollow">ISP</a>), because you end up with a swiss knife interface, like IQueryable for example.Ricardo Rodrigueshttps://www.blogger.com/profile/07328669019913577877noreply@blogger.com