2009-01-14 18 views
6

me gustaría hacer lo siguiente, pero no creo que esto va a funcionar:¿Puedo invocar una función en una expresión lambda?

.OrderByDescending(s => Score(s)), ... 


private double Score(Story s) 
     { 
      DateTime now = DateTime.Now; 
      TimeSpan elapsed = now.Subtract(s.PostedOn); 
      double daysAgo = elapsed.TotalDays; 

      return s.Votes.Count + s.Comments.Count - daysAgo; 
     } 

a. ¿Debería esto funcionar? b. si no, ¿necesito consultar las historias y luego ordenarlas por el puntaje?

+0

¿Este LINQ-to-Objects? ¿O LINQ-to-SQL? EF? Hace una diferencia. –

Respuesta

4

Sí, eso debería funcionar si la secuencia es una secuencia de Story elementos; ¿Qué problema estás teniendo? Tenga en cuenta que si Score no se aplica a ninguna instancia, podría valer la pena hacerlo estático.

Otra opción es hacer que el método Score() sea un método de instancia en un Story, o un método de extensión.

Tenga en cuenta que esto solo se aplica a LINQ-to-Objects; si está utilizando LINQ-to-SQL/LINQ-to-Entities, etc., necesita usar un lambda para todo o (en LINQ-to-SQL solamente) usar una función mapeada UDF (en los datos- contexto) para calcular el valor.

Ejemplo (LINQ a Objetos) con la sintaxis original:

using System.Linq; 
using System; 
class Story { // declare type 
    public DateTime PostedOn { get; set; } 
    // simplified purely for convenience 
    public int VotesCount { get; set; } 
    public int CommentsCount { get; set; } 
} 
static class Program { 
    static void Main() { 
     // dummy data 
     var data = new[] { 
      new Story { PostedOn = DateTime.Today, 
       VotesCount = 1, CommentsCount = 2}, 
      new Story { PostedOn = DateTime.Today.AddDays(-1), 
       VotesCount = 5, CommentsCount = 22}, 
      new Story { PostedOn = DateTime.Today.AddDays(-2), 
       VotesCount = 2, CommentsCount = 0} 
     }; 
     var ordered = data.OrderByDescending(s=>Score(s)); 
     foreach (var row in ordered) 
     { 
      Console.WriteLine(row.PostedOn); 
     } 
    } 

    private static double Score(Story s) { 
     DateTime now = DateTime.Now; 
     TimeSpan elapsed = now.Subtract(s.PostedOn); 
     double daysAgo = elapsed.TotalDays; 
     // simplified purely for convenience 
     return s.VotesCount + s.CommentsCount - daysAgo; 
    } 
} 

Añadir un this (es decir Score(this Story s)), y se puede utilizar:

.OrderByDescending(s=>s.Score()) 
2

En una nota menor de edad, puede escribir

.OrderByDescending(Score) 

ya que la firma "Score" cumple con la firma requerida.

Cuestiones relacionadas