-3

What is the shortest possible way of coding in C# where an action is performed on an object (Properties updated or Methods called etc) and is returned in a code block? Note, this will be used for small code actions, for example updating 1 or 3 properties.

Is there some way of using anonymous functions, Lambda, Action etc to make the code as small as possible? A kind of Fluent style. This will be mainly used as part of larger Lambdas.

The length of identifier names is not important, the shortest code construct is. Example here not really significant, only that ANY object needs to have 1 or 2 properties updated before being passed into to another Method call.

Example I wish to do this:

        public class Test2
        {
            void Display(Person p) => Console.Write(p.Name);

            //intentionally this will not compile, what is the least code to update p and return p.
            void ToAdultAndDisplay_XX(Person p){Display(p.Age = 21);}

            //using extension method
            void ToAdultAndDisplay_1(Person p) => Display(p.ActionOnSelf(i => i.Age = 21));

            //standard
            void ToAdultAndDisplay_2(Person p)
            {
                p.Age = 21;
                Display(p);
            }
        }

Note the Person object needs to be updated and returned, so that it can be passed into a method, all inline.

The following example below makes use of an Extension method ActionOnSelf that simply allows any object (in this example Person) to update itself via a Lambda.

void ToAdultAndDisplay_1(Person p) => Display(p.ActionOnSelf(i => i.Age = 21));

Questions:

  1. Does the code using ActionOnSelf use less code constructs vs any other code block, especially if updating a single property?

  2. Are there significant performance penalties using ActionOnSelf?

  3. Any alternative ways to perform this with the shortest amount of code?

The extension method is shown below:

using System;
namespace DevTestPlayground.ForStackOverflowExamples
{
    public static class LambdaExtensions
    {
        public static T ActionOnSelf<T>(this T o, Action<T> action)
        {
            action.Invoke(o);
            return o;
        }

        public static T ActionOnSelf<T>(this T o, params Action<T>[] actions)
        {
            foreach (Action<T> f in actions) f.Invoke(o);
            return o;
        }
    }
}
Rax
  • 665
  • 8
  • 19
  • 16
    Least code doesn't mean cleanest. Those one-liners are far harder to read than properly formatted code. `PersonMoodHandler` doesn't improve my mood, that's for sure – Panagiotis Kanavos Sep 24 '19 at 12:48
  • In fact, those one-liners aren't even visible – Panagiotis Kanavos Sep 24 '19 at 12:48
  • OK, I can't make heads or tails of this code. Some of it can be replaced with object initializers, other things though need careful reading over and over again just to understand which line does what and where. This is unreadable – Panagiotis Kanavos Sep 24 '19 at 12:51
  • This sounds like the ask is, essentially to some degree, *how to refactor most efficiently*? The answer generally is, *it depends*... ? – gravity Sep 24 '19 at 12:55
  • 2
    "Does this code "look" cleaner, especially if updating a single property?" To whom? Me? No. Why? Well, for one those one liners are way too long and have way too much is going on behind the scenes. The cleanest code (in my opinion) is made up of succinct statements where it is obvious what's going on. Also, lines of code is a horrible guideline for almost every metric – MindSwipe Sep 24 '19 at 12:55
  • 7
    [Code for the Maintainer](http://wiki.c2.com/?CodeForTheMaintainer): "Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live." – Damien_The_Unbeliever Sep 24 '19 at 12:57
  • 1
    I've been looking at it for a while now and to be honest I have no idea what it is supposed to do. I can kind of understand by the method names, but _why_ it is written like this, I have no idea. – FCin Sep 24 '19 at 12:57
  • 2
    SO you want to set a property eg "Name" on class Person. The shortest way I can think of doing this is: APerson.Name = "Dave"; I fail to understand why you would want to do it any other way. – Tim Rutter Sep 24 '19 at 12:58
  • 3
    If you're going for shortest code, your identifiers are way too long. Using Unicode characters, you can rename almost everything to a single character. ...and if that sounds like a terrible idea to you, it should be enough to cure you of the desire to go for "the shortest amount of code". In C#, whitespace is not significant, so you can always squash things on a single line if you so desire. You shouldn't, though. – Jeroen Mostert Sep 24 '19 at 12:59
  • 1
    @JeroenMostert ha ha indeed so. To demonstrate: public Person MakeHappy_standard(Person p){p.Comments = "Angry now";p.HappinessLevel = 10;return p;} would become public A B(A p){p.C = "Angry now"; p.D =10;return p;} – Tim Rutter Sep 24 '19 at 13:01
  • Thanks people, really useful feedback. I updated this so that we need to know what is the shorted code construct not including identifier names. – Rax Sep 24 '19 at 13:13
  • So basically what you are interested is some sort of fluent syntax to chain your method calls, whilst doing multiple actions per call? – Janne Matikainen Sep 24 '19 at 13:19
  • This question looks suspiciously like: https://stackoverflow.com/questions/57906370/c-sharp-expressional-if-statements-possible-expansion/57906908 – Corak Sep 24 '19 at 13:57
  • @Corak The two questions look completely different to me – TylerH Sep 24 '19 at 14:37
  • @TylerH - they are both: "(how to) return something but perform an action just before returning?" And in both cases the default way of "perform action first, *then* return" seems unsatisfactory to the person asking. – Corak Sep 24 '19 at 14:41

1 Answers1

2

The wave of comments saying exactly the same thing should give you a clue here. ActionOnSelf is not very nice code. It certainly doesn't 'look cleaner'. As everyone is saying good code isn't necessarily short. Good code does what it's supposed to do efficiently and is easy to understand. C# already has good syntax for doing basic operations on objects, you don't need to extend the language to do them. I'd argue the code below is better than any of your options.

public class PersonMoodHandler
{
    public Person MakeHappy(Person person)
    {
        person.HappinessLevel = 10;
        person.Comments = "Happy Now";
        return person;          
    }
}

public class Test
{
    public void DoStuffWithPerson()
    {
        Person person = new Person { Name = "Joe" };
        PersonMoodHandler personMoodHandler = new PersonMoodHandler();
        WritePersonComments(personMoodHandler.MakeHappy(person));
     }
}
Rich N
  • 8,939
  • 3
  • 26
  • 33