0

So, I have such class:

 public class PaymentsModel
    {
        [ReportsSummary(isGroupingSource:true)]
        public string PaymentType { get; set; }

        [ReportsSummary(isGroupingTarget: true)]
        public double Amount { get; set; }

        public string GuestName { get; set; }
}

I have List of (generic) which contains different objects with different values, for example:

{"Bank", 1, "K"},
{"Card", 2, "C"},
{"Cash", 3, "D"},
{"Bank", 2, "E"},
{"Card", 3, "G"},

I need a method CalculateSum() which will use generic class and reflection, and return Dictionary with grouping by PaymentType, and sum Amount for each PaymentType. So result should be:

[{"Bank", 3},
{"Card", 5},
{"Cash", 5}]

I created an attribute to understand, which property should be grouped, and which - summed:

 class ReportsSummaryAttribute : Attribute
    {
        public bool IsGroupingSource { get; private set; }
        public bool IsGroupingTarget { get; private set; }

        public ReportsSummaryAttribute(bool isGroupingSource = false, bool isGroupingTarget = false)
        {
            IsGroupingSource = isGroupingSource;
            IsGroupingTarget = isGroupingTarget;
        }
    }

But don't understand, how to create correct method.

  • 1
    That is a bit vague. Don't expect people to write your code, people gladly help you with your existing code. What have you tried? Show us your implementation. If you don't have one yet, here are some starters: [GetProperties](https://learn.microsoft.com/en-us/dotnet/api/system.type.getproperties?view=netcore-3.1), [GetCustomAttributes](https://learn.microsoft.com/en-us/dotnet/api/system.reflection.memberinfo.getcustomattributes?view=netcore-3.1). And for the sum, something fancy as [this](https://stackoverflow.com/questions/23404620/how-to-check-if-a-generic-has-an-operator-c-sharp) – dowhilefor Jun 16 '20 at 12:30
  • i dont understant if you have already a list, why do you want to use reflection? just grouping your fist item of list and amount? – Frenchy Jun 16 '20 at 12:31
  • @Frenchy sorry, I have a list of TModel, will update description – AtlasPromotion Jun 16 '20 at 12:33
  • ok how you build your list? could you show the code – Frenchy Jun 16 '20 at 12:36
  • @dowhilefor thank for useful links! I can found names of necessary properties using typeof(TPaymentsModel).GetProperties, and can found a value of each object in the list, using GetValue(). But how can I grouping values in a generic list by one specific property, and summing values of another properties – AtlasPromotion Jun 16 '20 at 12:37
  • @Frenchy I get it from some DTO methods, and result is: ```{"Bank", 1, "K"}, {"Card", 2, "C"}, {"Cash", 3, "D"}, {"Bank", 2, "E"}, {"Card", 3, "G"}```. Then I pass this list and class into generic class: ```new ReportsModel(paymentsList)```. Constructor also need generic type: ```public ReportsModel(List paymentsList)``` – AtlasPromotion Jun 16 '20 at 12:38
  • @AtlasPromotion you could try to use a Dictionary where the key is the grouping source and the value the owner object. Just as a start. – dowhilefor Jun 16 '20 at 12:40
  • @dowhilefor okay, but how can I find all possible values from one property using reflection, for Dictionary's keys? – AtlasPromotion Jun 16 '20 at 12:43
  • you want to know paymenttype which are not in list? – Frenchy Jun 16 '20 at 12:44
  • @AtlasPromotion You call the property with each individual object via reflection [GetValue](https://learn.microsoft.com/de-de/dotnet/api/system.reflection.propertyinfo.getvalue?view=netcore-3.1) – dowhilefor Jun 16 '20 at 12:45
  • @Frenchy, no, I need to create a Dictionary, which will contain all possible values of PaymentType from List, and sum of Amount for each PaymentType – AtlasPromotion Jun 16 '20 at 12:46

1 Answers1

0

a possible solution you could adapt:

public class MyGenericClass<T> where T:PaymentsModel//or common baseType
{

    public Dictionary<string, double> genericMethod(List<T> source)
    {
        var result = source.GroupBy(x => x.PaymentType)
            .Select(t => new { PaymentType = t.Key, Total = t.Sum(u => u.Amount) })
            .ToDictionary(t => t.PaymentType, t => t.Total);
        return result;
    }
}
:
:
//in processus
var myGenericClass = new MyGenericClass<PaymentsModel>();
var result = myGenericClass.genericMethod(source);
Frenchy
  • 16,386
  • 3
  • 16
  • 39