2010-03-03 21 views
14

Jestem nowy w funkcjonalnej stronie C#, przepraszam, jeśli pytanie jest lame.Przypisywanie własności anonimowego typu za pomocą anonimowej metody

Biorąc pod uwagę następujący kod ŹLE:

var jobSummaries = from job in jobs 
        where ... 
        select new 
        { 
         ID = job.ID, 
         Description = job.Description, 
         FileName = (job) => { 
            // primitive logic not 
            // worth to become a named method 
            try { return job.Files[0].LocalName); } 
            catch { return null as string; } 
           } 
        }; 

Kod ten tworzy następującą uzasadnioną błąd kompilatora:

cannot assign lambda expression to anonymous type property

Powyższy kod będzie ustawiony delegata do właściwości pliku. Ale to nie jest mój cel. Chcę, aby kod działał w ten sposób, ale bez nazywania metody:

var jobSummaries = from job in jobs 
        where ... 
        select new 
        { 
         ID = job.ID, 
         Description = job.Description, 
         FileName = this.ExtractFileName(job) 
        }; 

... 
private string ExtractFileName(Job job) 
{ 
    try { return Path.GetFileName(job.Files[0].LocalName); } 
    catch { return null as string; } 
} 

Jakieś sugestie?

Odpowiedz

16

Aby połączyć anonimową funkcję bezpośrednio, to działa:

int result = new Func<int, int>((int i) =>{ return i + 5; }).Invoke(3); 
// result = 8 

Ale zgadzam się, int result = (i => i + 5)(3); byłby sposób chłodnica =)

3

O ile mi wiadomo, nie można inline wyrażeń lambda jak ponieważ wyrażenie lamda jest samą instancją (typu Expression<Func<T>> lub podobną).

var jobSummaries = from job in jobs 
        where ... 
        let fileName = job.Files.Select(f => f.LocalName).FirstOrDefault() 
        select new 
        { 
         ID = job.ID, 
         Description = job.Description, 
         FileName = fileName 
        }; 

Zauważ użycie słowa kluczowego let, który pozwala wyodrębnić Nazwa pliku:

Jednak można to (zaktualizowane obliczenia pliku, ponieważ jest teraz zapewnione przez OP) zrobić ze zmiennej job bezpośrednio w wyrażeniu LINQ.

+0

Po prostu próbowałem. Nie mogę ustawić wyrażenia lambda jako zmiennej lokalnej z "let". Zaktualizowałem przykładowy kod. Mam próbę/catch, która utrudnia bezpośrednie przetwarzanie. – GarbageGuy

+0

Nie, nie można przypisać wyrażenia lambda do 'fileName'. Po prostu napisz kod: 'let fileName = Path.Combine (job.Folder, job.File)' lub jakakolwiek logika, której potrzebujesz ... –

+0

Dlaczego anonimowy downwise? –

2

Kompilator narzeka, bo nie wzywają swoją funkcję lambda, jesteś definiowania go. Jeśli kompilator by Ci pozwolił, miałbyś właściwość FileName, która jest funkcją, a nie wartością.

Jeśli możesz zapisać swoją "prymitywną logikę" jako wyrażenie, możesz to zapisać bezpośrednio w instrukcji przypisania.

0

Co powiesz na używanie rozszerzenia do wyboru. Więc możesz zrobić swoją małą logikę wewnątrz

Powiązane problemy