2009-05-12 35 views
7

Obecnie tworzę metodę rozszerzenia, która akceptuje parametry. Korzystając z poniższego przykładu, jak można go przekonwertować za pomocą wyrażeń lambda?Tworzenie metod rozszerzających za pomocą wyrażeń lambda

public static decimal ChangePercentage(this IEnumerable<Trade> trades, DateTime startDate, DateTime endDate) 
{ 
    var query = from trade in trades 
       where trade.TradeTime >= startDate 
       where trade.TradeTime <= endDate 
       orderby trade.TradeTime descending 
       select trade; 
    return (query.First().Value - query.Last().Value)/query.First().Value * 100; 
} 

Jakie są zalety/wady przy użyciu lambda vs normalne parametry metody?

Dzięki

+0

Co to znaczy „za pomocą wyrażeń lambda”? Jako filtr zamiast startDate/endDate? Zobacz odpowiedź Tima Robinsona. W przeciwnym razie, proszę opracuj. – Lucas

+0

To też było dla mnie niejasne. Podejrzewam, że odpowiedzi Tima i innych są prawdopodobnie tym, do czego dąży. – mquander

+0

Tak, to był filtr, którego szukałem. Nie wiedziałem, jak poprawnie to sformułować. W razie potrzeby zmień questoin :) –

Odpowiedz

8

Jednym ze sposobów zmiany próbki w celu użycia wyrażeń lambda jest użycie filtru.

public static decimal ChangePercentage(this IEnumerable<Trade> trades, Func<Trade,bool> pred) 
     { 
      var query = from trade in trades 
         where pred(trade); 
         orderby trade.TradeTime descending 
         select trade; 
      return (query.First().Value - query.Last().Value)/query.First().Value * 100; 
     } 

    someTrades.ChangePercentage(x => x.TradeDate >= startDate && x.TradeTime <= endDate); 

Największy profesjonalista, jaki daje to elastyczność. Zamiast posiadania metody polegającej na filtrowaniu daty do obliczeń. Masz metodę z elastycznym filtrem do obliczania procentów.

+0

+1 za zaoferowanie elastycznego rozwiązania. –

2

Twoja metoda domyślnie używa wyrażeń lambda.

Kiedy mówisz

trade.TradeTime >= startDate 

Co tak naprawdę jest powiedzenie „dali Trade zwany” trade „zwracają bool oceniając następujące:. trade.TradeTime >= startDate

To jest definicja tego lambda wyrażenia:

Func<Trade, bool> expr = (trade => trade.TradeTime >= startDate); 

aw rzeczywistości minus deklaracja expr, to jak byś go wyrazić, jeśli były przy użyciu składni złożenie funkcji dla LINQ zamiast składnia zapytania.

5

Czy chcesz zastąpić parametry startDate i endDate jednym wyrażeniem lambda?

public static decimal ChangePercentage(this IEnumerable<Trade> trades, DateTime startDate, DateTime endDate) 
{ 
    return trades.ChangePercentage(trade => trade.TradeTime >= startDate 
     && trade.TradeTime <= endDate); 
} 

public static decimal ChangePercentage(this IEnumerable<Trade> trades, Func<Trade, bool> filter) 
    { 
     var query = from trade in trades 
        where filter(trade) 
        orderby trade.TradeTime descending 
        select trade; 
     return (query.First().Value - query.Last().Value)/query.First().Value * 100; 
    } 
0

Jeśli nie chcesz parametrów, możesz przenieść filtrowanie na zewnątrz.

public static decimal ChangePercentage(this IEnumerable<Trade> trades) 
{ 
    var query = trades.OrderByDescending(t => t.TradeTime); 

    if (query.Any()) 
    return (query.First().Value - query.Last().Value)/query.First().Value * 100; 
    else 
    return 0; 
} 

Następnie można nazwać tak:

DateTime startDate, DateTime endDate 

decimal answer = ChangePercentage 
(
    from trade in trades 
    where trade.TradeTime >= startDate 
    where trade.TradeTime <= endDate 
    select trade 
); 
0

Kontynuując Tim's answer, można również zapewnić lambda wykonać obliczenia:

public static decimal ChangePercentage(
     this IEnumerable<Trade> trades, 
     Func<Trade, bool> filter, 
     Func<Trade, Trade, decimal> calc) 
    { 
     var query = from trade in trades 
        where filter(trade) 
        orderby trade.TradeTime descending 
        select trade; 
     return calc(query.First(), query.Last()); 
    } 

Zastosowanie:

trades.ChangePercentage(
     trade => (trade.TradeTime >= startDate && trade.TradeTime <= endDate), 
     (t1, t2) => (t1.Value - t2.Value)/t1.Value * 100 
    ); 
0

To ja Istotne jest zrozumienie, że wyrażenia Lambda służą innemu celowi niż metody rozszerzające. Wyrażenia lambdy są używane przede wszystkim jako kompaktowa składnia do definiowania implementacji implementacji lub funkcji delegata. Dodatkową zaletą wyrażeń lambda jest to, że można zdefiniować procedury obsługi zdarzeń i funkcje w treści innej funkcji, przydatne, jeśli masz prostą funkcję, która jest używana tylko w ramach określonej metody. Po prostu zdefiniuj funkcję za pomocą typu Func <> lub Action <> ze składnią lamda.

Polecam pobranie kopii C# In Depth Jona Skeeta. Obejmuje szczegółowo te tematy.

Oto ta funkcja jako wyrażenie lambda

private void Form1_Load(object sender, EventArgs e) 
     { 
      //signature of our function 
      Func<IEnumerable<Trade>, DateTime, DateTime, decimal> changePercentage = null; 

      //function implemented using lambda expression syntax 
      changePercentage += (trades, startDate, endDate) => 
      { 
       var query = from trade in trades 
          where trade.TradeTime >= startDate 
          where trade.TradeTime <= endDate 
          orderby trade.TradeTime 
          descending 
          select trade; 
       return (query.First().Value - query.Last().Value)/query.First().Value * 100; 
      }; 
     } 
Powiązane problemy