Passing object of anonymous type as parameter to a method

12,368

Solution 1

In general, it's almost always a bad idea to pass anonymous types between methods.

You should make a custom type to hold the nome and id values, then construct it instead of an anonymous type.


In your case, you already have a class that would work: carros. You can just implement your query to create it instead:

var queryResult = from q in cars 
  where q.nome.ToLower().Contains("eco") 
  orderby q.nome 
  select new carros {q.nome, q.id};

Your method would then be:

public void doSomething(IEnumerable<carros> queryResults)

Solution 2

Just wanted to chime in regarding passing anonymous types, while it's been mentioned that its bad juju to pass anonmyous types, you can... if you really wanted to (leveraging dynamic)

public void Anon()
{
     var x = new {foo = "bar"};

     AnonReciever(x);
}

public static void AnonReciever(dynamic o)
{
     Console.WriteLine(o.foo);
}

And this prints bar no problem.

I don't recommend it though. Best to use a custom typed object, which you already have.

Solution 3

You cannot pass anonymous types* outside the scope of the current method. Use your carros type:

public void listar_carros()
{
    List<carros> Lcars = new List<carros>();
    Lcars.Add(new carros(1, "Fusca"));
    Lcars.Add(new carros(2, "Gol"));
    Lcars.Add(new carros(3, "Fiesta"));

    var qry = from q in Lcars
              where q.nome.ToLower().Contains("eco")
              orderby q.nome
              select q;

    doSomething(qry);

}

public void doSomething(IEnumerable<carros> qry)
{

    foreach (carros ca in qry)
    {
        Response.Write(ca.nome);
        Response.Write(" - ");
        Response.Write(ca.id);
        //Response.Write(ca);
        Response.Write("<br />");
    }
}

* You can pass them only as an object which is mostly useless since you would want to use them in strong-typed way.

Solution 4

Why not declare the new object as type carros?

var qry = from q in Lcars 
          where q.nome.ToLower().Contains("eco") 
          orderby q.nome 
          select new carros {q.nome, q.id};

Your parameter would then:

 IEnumerable{carros}
Share:
12,368
Felipe Maricato Moura
Author by

Felipe Maricato Moura

Just code to live

Updated on June 04, 2022

Comments

  • Felipe Maricato Moura
    Felipe Maricato Moura almost 2 years

    I need do something like this:

    public class carros 
    {
        public int id { get; set; }
        public string nome { get; set; }
    }
    
    public void listar_carros()
    {
        List<carros> cars = new List<carros>();
        cars.Add(new carros{ id= 1, nome = "Fusca" });
        cars.Add(new carros{ id= 2, nome = "Gol" });
        cars.Add(new carros{ id= 3, nome = "Fiesta" });
    
        var queryResult = from q in cars 
                          where q.nome.ToLower().Contains("eco") 
                          orderby q.nome 
                          select new { q.nome, q.id };
    
        doSomething(queryResult)
    }
    

    I need to pass the queryResult variable to function doSomething(). I tried use a dynamic type, List<T> object, but nothing works

    public void doSomething(???? queryResult)
    {
        foreach (carros ca in queryResult)
        {
            Response.Write(ca.nome);
            Response.Write(" - ");
            Response.Write(ca.id);
        }
    }
    
  • Itanex
    Itanex almost 11 years
    Can you explain why this is a bad idea? He has an object already called Carros which has nome and id
  • Felipe Maricato Moura
    Felipe Maricato Moura almost 11 years
    dont work dynamic show error "namespace dynamic cannot be found"
  • Felipe Maricato Moura
    Felipe Maricato Moura almost 11 years
    erro: Error 3 'testeLINQ.carros' does not contain a constructor that takes 0 arguments
  • Felipe Maricato Moura
    Felipe Maricato Moura almost 11 years
    sorry works fine using a selec q; but not work for select new carros {q.nome, q.id}; or select new {q.nome, q.id}; do you know what?
  • Andrew Coonce
    Andrew Coonce almost 11 years
    @FelipeMaricatoMoura: The reason it's a bad idea is because the anonymous type that you've created is anonymous. That is: there's no way to construct it outside of the LINQ query where it was used (outside of reflection hackery). As helpful as anonymous types are, they are rightfully limited in scope to their initial method. If you want to pass them, they clearly have relevance beyond that initial scope and thus, are deserving of a name and a declaration.
  • Andrew Coonce
    Andrew Coonce almost 11 years
    @FelipeMaricatoMoura: So you changed the presented code example and then complained that your change has a bug (when the original code didn't)?
  • Felipe Maricato Moura
    Felipe Maricato Moura almost 11 years
    error show on word new in code select new carros {q.nome, q.id}; erro: Error 3 'testeLINQ.carros' does not contain a constructor that takes 0 arguments –
  • Felipe Maricato Moura
    Felipe Maricato Moura almost 11 years
    error show on word new in code select new carros {q.nome, q.id}; erro: Error 3 'testeLINQ.carros' does not contain a constructor that takes 0 arguments –
  • Reed Copsey
    Reed Copsey almost 11 years
    @FelipeMaricatoMoura The problem is that you're not showing your carros class - the code you posted would have a default constructor. You may need to use select new carros(q.nome, q.id) or similar, depending on how your class is actually defined.