3
\$\begingroup\$

So I have some POCO classes like this:

public record Party
{
    public string? Location{ get; set; }
    public string? Guests{ get; set; }
    public string? Drinks{ get; set; }
}

and I have this struct which has many methods that are very very similar. I wanted your idea on how can I write this with less copy-pasted code. Notice the pattern of those Make* methods are very similar**.

public struct NamedSet
{
    public NamedSet(string Name, string IdValue)
    {
        IdName = Name;
        Id = IdValue;
    }
    
    public static NamedSet MakeLocation(string? value)
    {
        const string name = nameof(Party.Location);
        return string.IsNullOrEmpty(value) ? MakeBlank(name) : new NamedSet(name, value);
    }

    public static NamedSet MakeGuests(string? value)
    {
        const string name = nameof(Party.Guests);
        return string.IsNullOrEmpty(value) ? MakeBlank(name) : new NamedSet(name, value);
    }

    public static NamedSet MakeDrinks(string? value)
    {
        const string name = nameof(Party.Drinks);
        return string.IsNullOrEmpty(value) ? MakeBlank(name) : new NamedSet(name, value);
    }
    
    public static NamedSet MakeBlank(string name)
    {
        return string.IsNullOrEmpty(name) ? new NamedSet("", "") : new NamedSet(name, "");
    }
    
}

and the way I use it is that when I have a list of my Party objects or other classes objects, I can call it call this:

p.MakeDrinks(p.Drinks)

I even have another class say House with say properties like

public record House
{
    public string? Windows{ get; set; }
    public string? Doors{ get; set; }
    public string? Carpets{ get; set; }
}

then again I have to go to my NamedSet and add a method like this:

public static NamedSet MakeDoors(string? value)
{
    const string name = nameof(House.Doors);
    return string.IsNullOrEmpty(value) ? MakeBlank(name) : new NamedSet(name, value);
}

public static NamedSet MakeCarpets(string? value)
{
    const string name = nameof(House.Carpets);
    return string.IsNullOrEmpty(value) ? MakeBlank(name) : new NamedSet(name, value);
}

You see there is a bunch of similr code. How can I make it better?

\$\endgroup\$
3

1 Answer 1

8
\$\begingroup\$

Reduce the repetitive code

  1. Extract the repetitive code into a dedicated method
private static NamedSet Make(string name, string? value)
  => string.IsNullOrEmpty(value) ? MakeBlank(name) : new NamedSet(name, value);
  1. Use it everywhere
public static NamedSet MakeLocation(string? value)
 => Make(nameof(Party.Location), value);

public static NamedSet MakeGuests(string? value)
 => Make(nameof(Party.Guests), value);

...

Single generic Make method

  1. Use property selector and reflection
private static string GetPropertyName<TSource, TProperty>(Expression<Func<TSource, TProperty>> propertySelector)
    => ((MemberExpression)propertySelector.Body).Member.Name;

public static NamedSet Make<TSource, TProperty>(Expression<Func<TSource, TProperty>> propertySelector, string? value)
{
   string name = GetPropertyName(propertySelector);
   return string.IsNullOrEmpty(value) ? MakeBlank(name) : new NamedSet(name, value);
}
  1. Use it
_ = Make<Party, string>(p => p.Location, "");
\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.