Alternative to adding new fields in Model

76 Views Asked by At

I have my model class like below

public class MyModel
{
   public string Id { get; set; } = string.Empty;
   public string Name { get; set; } = string.Empty;
   public int Age{ get; set; }
   public string AgeDisplay { get; set; } = string.Empty;    
}

You can see i have added one unncessary property called AgeDisplay Somewhere in code i change AgeDisplay based on condition like

if (Age > 18)
   AgeDisplay = "Adult";
else
   AgeDisplay = "Child";

I bind AgeDisplay to my mudtable. I feel its wrong way to add extra property to model. What is other alternative?

2

There are 2 best solutions below

2
On BEST ANSWER

This is an example of Primitive Obsession. Age is not an integer. Int.MinimumValue is not a valid age.

You can create a value type Age and then encapsulate all the necessary logic within Age.

Here's an example that also demonstrates some basic validation:

    public readonly record struct Age
    {
        public int Value { get; private init; }

        public bool IsAdult => this.Value > 18;

    public string TypeString => this.Value switch
        {
            < 1 => "Baby",
            < 12 => "Child",
            < 20 => "Teenager",
            < 65 => "Adult",
            _ => "Pensioner"
        };

        public Age(int value)
        {
            if (value < 0)
                throw new Exception("Age Can't be less that 0");

            this.Value = value;
        }
    }


    public class MyModel
    {
        public string Id { get; set; } = string.Empty;
        public string Name { get; set; } = string.Empty;
        public Age Age { get; set; }
        public string AgeDisplay { get; set; } = string.Empty;
    }
    MyModel _model = new() { Age = new(27) };

A second quick and dirty way is to create an extension class:

public static class AgeExtensions
{
    public static string AgeType(this int value)
        => value > 18 ? "Adult" : "Child";
}

Which you can then use like this:

var value = 20;
var type = value.AgeType();
0
On

If you really don't want to add more properties to the class and render different table column based on an existing property then you can do the following.

<MudTable Items="_people" Hover="true" Breakpoint="Breakpoint.None">
    <HeaderContent>
        <MudTh>Id</MudTh>
        <MudTh>Name</MudTh>
        <MudTh>Age</MudTh>
        <MudTh>Age Group</MudTh>
    </HeaderContent>
    <RowTemplate>
        <MudTd DataLabel="Id">@context.Id</MudTd>
        <MudTd DataLabel="Name">@context.Name</MudTd>
        <MudTd DataLabel="Age">@context.Age</MudTd>
        <MudTd DataLabel="AgeGroup">@GetAgeGroup(context.Age)</MudTd>
    </RowTemplate>
</MudTable>

@code { 
    List<Person> _people = new()
    {
        new Person(){Id="1",Name="Name1",Age=10},
        new Person(){Id="2",Name="Name2",Age=18},
        new Person(){Id="3",Name="Name3",Age=21},
        new Person(){Id="4",Name="Name4",Age=65}
    };
    string GetAgeGroup(int age) 
    {
        switch (age)
        {
            case int n when n < 18:
                return "Child";
            case int n when n >= 18 && n < 65:
                return "Adult";
            case int n when n >= 65:
                return "Senior";
            default:
                return "Undefined";
        }
    }
    public class Person
    {
        public string Id { get; set; }
        public string Name { get; set; } 
        public int Age{ get; set; }
    }
}

MudBlazor Snippet