-1

I have an object <Repere> whose structure is the following :

class Repere
{
    public string Name { get; set; }
    public List<Operation> Operations { get; set; }
    public int Quantite {get;set;}
    ...
}

When I want to group a List<Repere> by its name, I always use the following grouping method :

List<Repere> liste_rep_group = liste_rep.GroupBy(l => l.Name)
    .Select(cl => new Repere
    {
        Quantite = cl.Sum(c => c.TotalQuantity),
        TotalQuantity = cl.Sum(c => c.TotalQuantity),
        ID = -1,
        IdAff = cl.First().IdAff,
        Name = cl.First().Name,
        NameOri = cl.First().Name,
        Nom_aff = cl.First().Nom_aff,
        Profil = cl.First().Profil,
        Longueur = cl.First().Longueur,
        Hauteur = cl.First().Hauteur,
        Largeur = cl.First().Largeur,
        Poids = cl.First().Poids,
        Priorite = cl.Min(c => c.Priorite),
        Matiere = cl.First().Matiere,
        Angle1 = cl.First().Angle1,
        Angle2 = cl.First().Angle2,
        AngleAile1 = cl.First().AngleAile1,
        AngleAile2 = cl.First().AngleAile2,
        GroupeProfil = cl.First().GroupeProfil,
        ListOperations = (cl.SelectMany(g=>g.ListOperations).GroupBy(o=>o.ID)
            .Select(go => new Operation
                {
                    ID = go.First().ID,
                    QtyFinished = go.Sum(o => o.QtyFinished),
                    Color=go.First().Color,
                })).ToList()
        ...
    }).ToList();

What I would liek to do is add in my class Repere a method like

public List<Repere> GroupByName(List<Repere>)
{
   //My grouping method
}

So everytime I need to group my List<Repere>, I don't need to copy all the function everywhere.The main reason is that when I modify Repere structure, I need to edit function, and there are risks to forget to update it somewhere.

Siegfried.V
  • 1,508
  • 1
  • 16
  • 34
  • Ok, so why don't you? What is your question? You can pass a `IQueryable` as parameter to your function. – nbokmans Jan 31 '19 at 08:19
  • 1
    You could create a static helper method or an extension method. @nbokmans I dont think thats necessary – Jota.Toledo Jan 31 '19 at 08:21
  • @nbokmans because I don't know how to do, if you could at least give me some "key words" so I would know what to search for ? Will already begin looking for what is an IQueryable, thanks – Siegfried.V Jan 31 '19 at 08:24
  • 1
    @Jota.Toledo that is the most dynamic solution however. `IQueryable` is a database query that has not yet been resolved into a result (usually done by `ToList()` or `ToArray()` call). So in some cases you want to apply filtering (`Where` clauses) on the set of `Repere`'s you want to return, and it's usually better to do that filtering on the database level than in memory. – nbokmans Jan 31 '19 at 08:26
  • @Jota.Toledo if I understood good, put that method in a static library? In fact I have a static library in which I put universal functions(as calculate surface of a form), but I believed that as this function concerns my class Repere, its place was in Repere class – Siegfried.V Jan 31 '19 at 08:27
  • @nbokmans so you also would advise static function? I believed thare was a way to do something like `MyList.GroupByName()` – Siegfried.V Jan 31 '19 at 08:28
  • Ok I will do using static function then, thanks for your answers – Siegfried.V Jan 31 '19 at 08:30
  • I think I'd prefer extension methods (see Ramesh' answer) over static functions. – nbokmans Jan 31 '19 at 08:30
  • @nbokmans you are making the assumption that OPs question has some relation to some form of DB, which might not be the case. – Jota.Toledo Jan 31 '19 at 08:32
  • in fact I read his answer, I don't see the difference except it's in a separate static class(don't know about extension methods but I go read about it right now) – Siegfried.V Jan 31 '19 at 08:32
  • and in fact, it is not related to DB – Siegfried.V Jan 31 '19 at 08:32
  • 1
    @Siegfried.V _I believed that as this function concerns my class Repere_ the one thing that you are currently doing that relates directly to a class instance is the *cloning* operation. You could capsulate that into a `static Repere FromInstance(Repere source)` class method. The grouping operation itself is related to the collection of `Repere` instances, for that reason an extension method would be convenient, but not mandatory. – Jota.Toledo Jan 31 '19 at 08:34
  • @Jota.Toledo I asked because I was wondering about the "most correct" way to implement it. But seems the Extension method is the best solution for me. – Siegfried.V Jan 31 '19 at 08:40
  • @Jota.Toledo excuse me, could you explain me why some people downvotes this kind of questions? Is this considered as stupid question or what? – Siegfried.V Feb 01 '19 at 15:58

1 Answers1

1

You may write an extension method on the List<Repere> to achieve the intended behavior.

public static class ListRepereExtensionMethods
{
    public static List<Repere> GroupByName(this List<Repere> liste_rep)
    {
        List<Repere> liste_rep_group = liste_rep.GroupBy(l => l.Name)
            .Select(cl => new Repere
            {
                Quantite = cl.Sum(c => c.TotalQuantity),
                TotalQuantity = cl.Sum(c => c.TotalQuantity),
                ID = -1,
                IdAff = cl.First().IdAff,
                Name = cl.First().Name,
                NameOri = cl.First().Name,
                Nom_aff = cl.First().Nom_aff,
                Profil = cl.First().Profil,
                Longueur = cl.First().Longueur,
                Hauteur = cl.First().Hauteur,
                Largeur = cl.First().Largeur,
                Poids = cl.First().Poids,
                Priorite = cl.Min(c => c.Priorite),
                Matiere = cl.First().Matiere,
                Angle1 = cl.First().Angle1,
                Angle2 = cl.First().Angle2,
                AngleAile1 = cl.First().AngleAile1,
                AngleAile2 = cl.First().AngleAile2,
                GroupeProfil = cl.First().GroupeProfil,
                ListOperations = (cl.SelectMany(g=>g.ListOperations).GroupBy(o=>o.ID)
                    .Select(go => new Operation
                        {
                            ID = go.First().ID,
                            QtyFinished = go.Sum(o => o.QtyFinished),
                            Color=go.First().Color,
                        })).ToList()
                ...
            }).ToList();
    }
}

When using the above extension method you can call the method like

List<Repere> liste_rep_group = liste_rep.GroupByName();

You can choose to implement this as a static Utility class as well. In that case you will remove the this from the parameter section of the method and will invoke the method like

List<Repere> liste_rep_group = ListRepereExtensionMethods.GroupByName(liste_rep);

Some discussions on pros and cons of the approach is available at Extension Methods vs Static Utility Class evaluating cost/benefits of using extension methods in C# => 3.0

Ramesh
  • 13,043
  • 3
  • 52
  • 88