Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

383
Visualizações
Linq: Group by that groups results differently according to a variable (enum for example)

I'm trying to run a query where the 'GroupBy' clause will group the results differently according to say, an enum value which would be databound to a combobox etc.

I tried to do this with a switch case, but this resulted in compiler error CS0411 on the 'GroupBy' clause, because as I understand it, the type of the object returned from the lambda will be different depending on which case is executed.

How can I neatly achieve this functionality?

I have enclosed a minimal example of the problem below, as a console program.

class Program
{
    static List<Person> People;

    enum GroupBy
    {
        Month,
        Year
    }

    static void Main(string[] args)
    {            
        People = new List<Person>();

        People.Add(new Person()
        {
            Dob = new DateTime(2000,10,1),
            Name = "James",
            IsSelected = false               
        });
        People.Add(new Person()
        {
            Dob = new DateTime(2000, 5, 1),
            Name = "Anne",
            IsSelected = true
        });
        People.Add(new Person()
        {
            Dob = new DateTime(2000, 5, 23),
            Name = "Bob",
            IsSelected = true
        });
        People.Add(new Person()
        {
            Dob = new DateTime(1999, 1, 15),
            Name = "Kate",
            IsSelected = false
        });

        // Obviously, in the real thing, the grouping value would be
        // databound to a combobox or something.
        GroupBy grouping = GroupBy.Month;

        var groups = People
            .OrderBy(x => x.Dob)
            .GroupBy(x => /* PROBLEM LINE - Gives compiler error CS0411 */
            {
                switch(grouping)
                {
                    case GroupBy.Month:
                        return new { x.Dob.Year, x.Dob.Month };
                    case GroupBy.Year:
                        return new { x.Dob.Year};
                    default:
                        throw new Exception("No can do");
                }
            });

        Console.WriteLine("Grouping is: " + grouping + "\r\n");
        foreach(var group in groups)
        {
            Console.WriteLine("Group: " + group.Key);
            foreach(Person p in group)
            {
                Console.WriteLine("\t" + p.Name + ", " + p.Dob);
            }
            Console.WriteLine("");
       }

       Console.ReadKey();
           
    }
}

public class Person
{
    public DateTime Dob { get; set; }
    public string Name { get; set; }
    public bool IsSelected { get; set; }
}
over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

The problem occurs in your switch statement when returning anonymous types. The compiler cannot infer the type (because it is generated by the compiler for each separate projection) and throws an error as a result.

You can easily work around this by creating a wrapper class:

public class GroupedResult
{
    public int Year { get; set; }
    public int Month { get; set; }
}
var groups = People
    .OrderBy(x => x.Dob)
    .GroupBy(x => /* PROBLEM LINE - Gives compiler error CS0411 */
    {
        switch (grouping)
        {
            case GroupBy.Month:
                return new GroupedResult { Year = x.Dob.Year, Month = x.Dob.Month };
            case GroupBy.Year:
                return new GroupedResult { Year = x.Dob.Year };
            default:
                throw new Exception("No can do");
        }
    });

OR by ensuring that same properties exist on both anonymous types, resulting in the same compiler-generated type:

var groups = People
    .OrderBy(x => x.Dob)
    .GroupBy(x => /* PROBLEM LINE - Gives compiler error CS0411 */
    {
        switch (grouping)
        {
            case GroupBy.Month:
                return new  { Year = x.Dob.Year, Month = x.Dob.Month };
            case GroupBy.Year:
                return new  { Year = x.Dob.Year, Month = 0 };
            default:
                throw new Exception("No can do");
        }
    });
over 4 years ago · Santiago Trujillo Relatório

0

The simplest solution:

.GroupBy(x => new 
{ 
    Year = x.Dob.Year, 
    Month = grouping == GroupBy.Month ? x.Dob.Month : 0 
};
  • Year is always part of your grouping
  • Month will be part of your grouping only if grouping equals to Month
    • Otherwise use a constant << ergo no grouping

I would suggest to avoid to throw exception inside a GroupBy delegate.

  • Rather do a preliminary check and early exit.
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda