.NET i takie tam

LINQ ciąg dalszy

with 8 comments

Tym razem napiszę o problemie, na jaki natknąłem się korzystając z LINQ, otóż załóżmy, że mamy kolekcję zawierającą jako elementy obiekty typu np. Item. Teraz wykonuję jakąś kwerendzie LINQ i jako rezultat zwracam kolekcję niektórych właściwości klasy Item. Następnie otrzymaną listę bindujemy, do powiedzmy, kontrolki ComboBox. Wykonujemy jakieś operacje etc. a następnie chcemy pobrać zaznaczony obiekt poprzez ComboBox.SelectedItem. I tu pojawia się problem na jaki typ rzutować? Dla zobrazowania przykładowy kod:

class Item
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Value { get; set; }
    public double Scale { get; set; }

    // etc. jakieś inne właściwości

    public Item(int id, string name, int value, double scale)
    {
        Id = id;
        Name = name;
        Value = value;
        Scale = scale;
    }
}

List<Item> list = new List<Item>();
list.Add(new Item(1, "Item1", 101, 5.99));
...
list.Add(new Item(9, "Item9", 909, 7));

var query = from o in list
            where o.Id < 10 && o.Id > 4
            select new { o.Id, o.Name, o.Value };

cboTest.DataSource = query.ToList();
cboTest.DisplayMember = "Name";
cboTest.ValueMember = "Id";

Ponieważ w kwerendzie LINQ, zwracam typ generowany przez IL (tzw. anonymous type) nie mogę jawnie na niego rzutować, i tym samym zastosowanie typów object czy var nic mi nie daje (tj. dostępu do właściwości typu). Zawsze można skorzystać z mechanizmu refleksji, jednak nie jest to ścieżka którą chciałbym podążyć. Szukam raczej jakiegoś ‚schludnego’ podejścia do tego ograniczenia/ciekawostki. Jakieś pomysły?

Written by sakowicz

Styczeń 9, 2008 @ 11:07 am

Napisane w .NET

Odpowiedzi: 8

Subscribe to comments with RSS.

  1. Ja bym nie uzywal typu anonimowego. Troche wicej pisania ( o ile sie nie uzywa Resharpera) ale problem powinien byc rozwiazany.

    Pawel Pabich

    Styczeń 9, 2008 at 1:12 pm

  2. Jasne w rzeczywistej aplikacji, przedstawiony problem zwykle nie ma znaczenia bo istnieje szereg możliwości jego ominięcia. Ja traktuje to jako ciekawostkę i stawiam sobie pytanie czy jakoś się da to zrobić. Tylko tyle.

    sakowicz

    Styczeń 9, 2008 at 2:35 pm

  3. Daj znac jak cos wyczarujesz.

    Pawel Pabich

    Styczeń 10, 2008 at 10:24 am

  4. Nie omieszkam😉 Jednak mam nieodparte wrażenie, że to jest jedno z ograniczeń zastosowania, typów anonimowych.

    sakowicz

    Styczeń 10, 2008 at 11:25 am

  5. Nie wiem o jakie rzutowanie ci chodzi konkretnie?

    Ale może to rozwiąże Twój problem:

    cboTest..DataTextField = “Name”;
    cboTest.DataValueField = „Id”;
    cboTest.DataBind();

    Napisz koniecznie dokładnie o co Ci chodziło

    SaX

    Kwiecień 26, 2008 at 6:35 am

  6. Nie w bindowaniu problem. Bindujemy nasze ‚anonimowe’ obiekty do kontrolki np. ComboBox. Użytkownik robi swoje i zaznacza co potrzebuje, my przechwytujemy zdarzenie SelectedIndexChanged i chcemy odczytać aktualnie zaznaczony obiekt w kontrolce z pomocą SelectedItem – pytanie na jaki typ rzutować skoro wcześniej korzystaliśmy z typu anonimowego.

    Jeśli się nie mylę i dobrze pamiętam jest to aktualnie nieosiągalne, ze względu bodaj na zasięg typu anonimowego.

    sakowicz

    Kwiecień 26, 2008 at 1:05 pm

  7. Zaiste, odzyskać dla kodu zmienną – rzecz niepodobna.
    Azaliż nacechowanych zaciekłością srogą próbach kilku w materii mienionej, ku mniemaniu się skłaniam iż w cierpliwość wyposażyć się trzeba i na .NET 4.0 wytrwale czas czekać, kędy twórcy szacowni niedoskonałość tę dostrzegą i ku ukontentowaniu ogólnemu usunąć ją raczą.
    Ponad mienione niewygody, mężowie dostojni, zauważyć tę pragnę, że zmienną anonimową jako globalną w klasy ciele zadeklarować nie sposób.

    człowiek

    Marzec 24, 2009 at 9:08 pm

  8. Po pierwsze w twoim przypadku spokojnie możesz wyciągnąć listę pełnych Item’sów, bo skoro wyciągasz coś z wcześniej utworzonej listy, to takie wyrażenie nie wpłynie w żaden sposób na ilość zajmowanej przez aplikację pamięci.

    W przypadkach pozostałych zalecam stworzenie normalnej klasy, która dane Ci przechowa… typy anonimowe są dobre, ale tylko do niektórych zastosowań. Zgodnie z wolą ich twórców są raczej pojemnikami do tymczasowego przechowywania danych do natychmiastowej obróbki.

    Pozdrawiam

    Łukasz

    Wrzesień 20, 2010 at 7:31 pm


Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Log Out / Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Log Out / Zmień )

Facebook photo

Komentujesz korzystając z konta Facebook. Log Out / Zmień )

Google+ photo

Komentujesz korzystając z konta Google+. Log Out / Zmień )

Connecting to %s

%d bloggers like this: