Aktualizacja: rozwiązanie podane na końcu postu – brawa dla Roberta i Gekona :)
Aktualizacja: Kod się nie kompiluje i o to chodzi. Trzeba go doprowadzić do stanu w którym będzie się kompilował i będzie zwracał oczekiwany rezultat. Dodatkowo usunąłem using dla Linq.
Mamy następujący kod:
using System;
using System.Collections.Generic;
using System.Text;
namespace HelloWorldTest
{
public class Items<T>
{
public T Item;
public override string ToString()
{
return Item.ToString();
}
}
public class Program
{
public static void Main(string[] args)
{
var items = new Items<int> { Item = 1 };
var query = from item in items
where item.ToString() == "1"
select new { items = item };
Console.ReadLine();
}
}
}
Jak możemy uzyskać następujący wynik (oraz dlaczego):
Hello |
| World
Przy założeniach, że nie możemy modyfikować kodu klasy Items<> i Program.
Rozwiązanie
Zarówno Robert jak i Gekon dobrze odpowiedzieli :) Poniżej zamieszczam implementację wykonaną przez Roberta. By zadziałała należy dodać klasę do głównej przestrzeni nazw:
public static class Ext
{
public static Items<int> Select(this Items<int> source, Func<Items<int>, object> selector)
{
return null;
}
public static Items<int> Where(this Items<int> source, Func<Items<int>, bool> predicate)
{
Console.WriteLine("Hello |");
Console.WriteLine("| World");
return null;
}
}
Oczywiście nic nie stoi na przeszkodzie by int był generyczny (T). Teraz małe info dlaczego to zadziała.
Kompilator zamienia nasze wyrażenie na wywołanie metod:
Items<int> query = items.Where(item => (item.ToString() == "1")).Select(item => new { items = item });
Dlatego tak prosta operacja jak extension methods – czy też metody publiczne w klasie Items<T> - załatwią problem.
PS.: Jeżeli uważacie iż nazwa Challenge jest nie odpowiednia, to w komentarzach podajcie propozycje jak nazywać taką serię. Dzięki!