1

I have two classes which contain the 12 months as object names and its values are decimal. I have to check whether class A object greater than class B object.

Class A
{
   decimal Jan;    
   decimal Feb;    
   decimal Mar;
}

Class B
{
   decimal Jan;    
   decimal Feb;    
   decimal Mar;
}

Right now, i am using if loop for all the object to check the validation.

if(A.Jan > B.Jan)
{
  return false;
}
else if(A.Feb > B.Feb)
{
  return false;
}
else if(A.Mar > B.Mar)
{
  return false;
}

Is there any mechanism to simplify this logic.

Sowmyadhar Gourishetty
  • 1,843
  • 1
  • 8
  • 15
Vignesh Kumar A
  • 27,863
  • 13
  • 63
  • 115
  • 1
    Use an array of decimals to hold the 12 months' values, then just loop over the array and have a single `if` in the loop body? – Matthew Watson Aug 24 '20 at 11:02
  • 2
    I don't know if this is due to simplification, but why do you need two different classes here? – Fildor Aug 24 '20 at 11:04
  • are you asking how to overload the > operator? – Hogan Aug 24 '20 at 11:25
  • Does this answer your question? [What are the basic rules and idioms for operator overloading?](https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-and-idioms-for-operator-overloading) – Hogan Aug 24 '20 at 11:26
  • see this answer https://stackoverflow.com/a/4421719/215752 – Hogan Aug 24 '20 at 11:26
  • @Fildor I have sampled here but in real time both are having different values and which needs to be compared. – Vignesh Kumar A Aug 24 '20 at 11:29
  • 1
    @VigneshKumarA That would be a reason to have two _instances_. But you define two different _types_ ... but anyway. I take it as it is. – Fildor Aug 24 '20 at 11:31
  • Will the two classes have the same property names? and in the same order? – Sowmyadhar Gourishetty Aug 24 '20 at 11:40
  • Implement IComparable/ IComparer on the classes and compare one with the other and override Compare method. This way you can compare one object with another. – JaisG Aug 24 '20 at 12:18

3 Answers3

1

Perhaps implement a function in the two classes that returns a collection of the month values. You can then compare them one by one.

void Main()
{
    var a = new A() { Jan = 1, Feb = 1, Mar = 5 };
    var b = new B() { Jan = 1, Feb = 1, Mar = 3 };

    Compare(a, b).Dump();
}

private bool Compare(A a, B b)
{
    var ae = a.GetMonthValues().GetEnumerator();
    var be = b.GetMonthValues().GetEnumerator();
    while (ae.MoveNext() & be.MoveNext())
    {
        if (ae.Current > be.Current)
            return false;
    }
    return true;
}

class A
{
    public decimal Jan;
    public decimal Feb;
    public decimal Mar;

    public IEnumerable<decimal> GetMonthValues() => new[] { Jan, Feb, Mar };
}

class B
{
    public decimal Jan;
    public decimal Feb;
    public decimal Mar;

    public IEnumerable<decimal> GetMonthValues() => new[] { Jan, Feb, Mar };
}

You can also extract an interface with the GetMonthValues function and let both classes implement that. (and the month properties if desired)

Fildor
  • 14,510
  • 4
  • 35
  • 67
Magnus
  • 45,362
  • 8
  • 80
  • 118
  • It would all be better if the storage of the month data was encapsulated in an object right? – Hogan Aug 24 '20 at 12:31
0

You could use operator overloading to do this -- like this:

inline bool operator< (const A& lhs, const B& rhs)
{
  /* do actual comparison */ 
}

see this question and answer

What are the basic rules and idioms for operator overloading?


You could also use the following pattern with an interface :

interface ExtractDate<T>
{
  decimal getDate(integer which);
}


Class A : ExtractDate<A>
{
   decimal getDate(integer which)
   {
     switch (which)
     {
       case 1 : return this.Jan; break;
       case 2 : return this.Feb; break;
       case 3 : return this.Mar; break;
     }
   }
   decimal Jan;    decimal Feb;    decimal Mar;
}

Class B : ExtractDate<B>
{
   decimal getDate(integer which)
   {
     switch (which)
     {
       case 1 : return this.Jan; break;
       case 2 : return this.Feb; break;
       case 3 : return this.Mar; break;
     }
   }
  decimal Jan;    decimal Feb;    decimal Mar;
}

Then you can say

 if(A.getDate(1) > B.getDate(1))
 {
    return false;
 }
 //etc

If it was me this seems like a lot of work -- I myself would make a object called DateInfo and have both objects implement that object (it is the same in both object) and then compare objects of the same type -- which is much easier.

Hogan
  • 69,564
  • 10
  • 76
  • 117
  • Thsnka for your answer but again the code which i need to write for all the object right? which i wanted to overcome by simply passing the class and it should found is there values greater and returtn true. – Vignesh Kumar A Aug 24 '20 at 12:04
  • @VigneshKumarA Your comment makes no sense. – Hogan Aug 24 '20 at 12:29
  • Why `T obj` in `getDate` and why `T` at all in the interface? – Magnus Aug 24 '20 at 12:31
0

You can combine class A and B into one class and then overload the compare operator, like this:

Class Year
{
   decimal Jan;    
   decimal Feb;    
   decimal Mar;
   
   private List<decimal> Months = new List<decimal> {Jan, Feb, Mar}

   public static bool operator<(Year a, Year b)
   {
      for(int i = 0; i < Months.Count; i++)
      {
          if(a.Months[i]<b.Months[i]) return true;
      }
      return true;
   }

   public static bool operator>(Year a, Year b)
   {
      for(int i = 0; i < Months.Count; i++)
      {
          if(a.Months[i]>b.Months[i]) return true;
      }
      return true;
   }
}

Also I introduced a list for the months so you do not have to if-else them separately

andy meissner
  • 1,202
  • 5
  • 15