seUser
seUser

Reputation: 1103

How to calculate total of all properties within the object in C#?

public class Calories
{
  public decimal A { get; set; }
  public decimal B { get; set; }
  public decimal C { get; set; }
  public decimal Total { get; set; }
}

var calories = new Calories
{ 
  A = 10, B = 25, C = 31
};

//Currently I am doing this
calories.Total = calories.A + calories.B + calories.C;

What is the efficient way to calculate total of all properties in the same object?

Upvotes: 0

Views: 2675

Answers (4)

David L
David L

Reputation: 33815

While this is dramatically slower than simply manually adding your decimals together and is somewhat rigid since you're explicitly excluding the Total property by string, the following reflection will total only your Decimal columns without breaking if it encounters a property that is not a decimal.

public class Calories
{
    public decimal A { get; set; }
    public decimal B { get; set; }
    public decimal C { get; set; }
    public string TestString { get;set;}

    public decimal Total 
    { 
        get
        {
            return typeof(Calories)
                .GetProperties()
                .Where (x => x.PropertyType == typeof(decimal) 
                    && x.Name != "Total")
                .Sum(p => (decimal)p.GetValue(this));
        }
    }
}

Keep in mind that either better class structure or Yuval's answer would be preferable since it properly maintains both strong typing AND performance. I added this as the "pure reflection" answer for completeness.

Finally, if you wanted to use reflection to dynamically access an unknown number of decimal properties but you wanted to avoid the heavy reflection cost, you could use a library like FastMember to mitigate the performance hit.

public class Calories
{
    public decimal A { get; set; }
    public decimal B { get; set; }
    public decimal C { get; set; }
    public string TestString { get;set;}

    public decimal Total 
    { 
        get
        {
            var accessor = FastMember.TypeAccessor.Create(this.GetType());

            return accessor.GetMembers()
                .Where (x => x.Type == typeof(decimal) && x.Name != "Total")
                .Sum(p => (decimal)accessor[this, p.Name]);
        }
    }
}

Upvotes: 2

Tim B
Tim B

Reputation: 2368

Doesn't really answer your question, but if you are open to a different design, and you want a class with an undetermined number of values with Total property..

class Calories : List<decimal>
{
    public decimal Total { get { return this.Sum(); } }
}

Might not be the best way.. depends on the circumstances, but fast and minimal code.

Upvotes: 5

C1rdec
C1rdec

Reputation: 1687

What I would do is create a List of Calories and inside your class you could have a Property Total that call Sum on your List

Like so:

public class Calories
{
  public List<decimal> Calories;
  public decimal Total{ get { return this.Calories.Sum(); } }

  public Calories()
  {
    this.Calories = new List<decimal>();
  }
}

Upvotes: 0

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149538

Yes. You can calculate the sum inside the property getter:

public decimal Total { get { return A + B + C } };

Upvotes: 15

Related Questions