2010-08-02 12 views
15

To jest mój kodu testu:Argument „pustka” nie jest przypisane do parametru typu „System.Action”

class PassingInActionStatement 
{ 
    static void Main(string[] args) 
    { 
     var dsufac = new DoSomethingUsefulForAChange(); 

     dsufac.Do(WriteToConsole); 
     dsufac.Do2(s => WriteToConsoleWithSomethingExtra("Test")); 
     dsufac.Do(WriteToConsoleWithSomethingExtra("Test")); // Does not compile 
    } 

    internal static void WriteToConsole() 
    { 
     Console.WriteLine("Done"); 
    } 

    internal static void WriteToConsoleWithSomethingExtra(String input) 
    { 
     Console.WriteLine(input); 
    } 
} 

internal class DoSomethingUsefulForAChange 
{ 
    internal void Do(Action action) 
    { 
     action(); 
    } 

    internal void Do2(Action<String> action) 
    { 
     action(""); 
    } 
} 

2 pierwszych rozmów działa, ale zastanawiam się, dlaczego 3rd jeden nie. Nie podoba mi się kod wewnątrz Do2, ponieważ wydaje się dziwne, że mam tam typ typu action(""), aby go uruchomić.

Czy ktoś mógłby wyjaśnić 2 rzeczy, których nie rozumiem?

  1. Dlaczego nie mogę pisać trzecią linię takiego z wywołaniem Wykonaj
  2. Dlaczego muszę napisać działanie („”) w celu zmusić go do pracy w DO2
+0

zawsze zaznaczone odpowiedzi, które pomogły mi. Jeśli nie ma rozwiązania, które zapewnia coś użytecznego, nie zaznaczam go, dopóki nie otrzymam odpowiedzi, która mi pomoże. –

Odpowiedz

32
dsufac.Do(WriteToConsoleWithSomethingExtra("Test")); 

faktycznie najpierw wywołuje funkcję (WriteToConsoleWithSomethingExtra("Test")), a następnie próbuje przekazać wynik do Do. Ponieważ nie ma wyniku (void), nie jest to możliwe.

Co rzeczywiście chcesz to:

dsufac.Do(() => WriteToConsoleWithSomethingExtra("Test")); 

Wewnętrzna część deklaruje funkcję, która pobiera nic (the () => bitowy), który wywołuje WriteToConsoleWithSomethingExtra("Test") gdy wykonywany. Następnie Twoje połączenie zostanie odebrane, tak jak się spodziewa.

chodzi o Do2 - masz zadeklarowane jako biorąc Action<String>, co oznacza, że ​​action to funkcja trwa jeden argument. Musisz przekazać mu ciąg znaków. Że łańcuch może być pusta, tak jak w przykładzie action(""), czy to może być przekazywane w zewnętrznie, jak coś takiego:

dsufac.Do3(WriteToConsole, "Test"); 

... 

internal void Do3(Action<String> action, String str) 
{ 
    action(str); 
} 
+0

Waw! To działa. Nadal mam wiele problemów z tymi rzeczami Action i Func. Czy są jakieś przyzwoite samouczki oprócz MSDN lub książek, które możesz polecić? Zaznaczę twoją odpowiedź jako taką, kiedy pozwoli mi (widocznie muszę poczekać na kolejne ... minuty). –

+0

Dzięki za dodatkową aktualizację. –

1
  1. Do oczekuje Action (czyli metodę, która nie podejmuje żadnych parametrów i nie zwraca wartości). Dlatego WriteToConsoleWithSomethingExtra nie jest prawidłowym pasowaniem - pobiera jeden parametr ciągu.
  2. Do2 akceptuje Action<T> (tj. Metodę, która przyjmuje jeden parametr T i nie zwraca żadnej wartości). Stąd, gdy wywołujesz delegata/akcję, musisz podać jeden parametr typu T, tutaj Ciąg.
3

W kodzie

dsufac.Do(WriteToConsoleWithSomethingExtra("Test")); 

jest interpretowany jak na poniższym

var variable = WriteToConsoleWithSomethingExtra("Test"); 
dsufac.Do(variable); 

jako typ zwracanej WriteToConsoleWithSomethingExtra ("Test") jest nieważna, więc nie można właściwie przekazać je do dsufac.Do(). Dlatego jego kompilacja się nie komplikuje. Ale dla pierwszego

dsufac.Do(WriteToConsole); 

nie jest wywołanie funkcji, raczej są przechodzącą go jako grupa metoda, która jest później powołano się w metodzie Do() obiektu dsufac.Ale jeśli chcesz napisać trzecią linię jako pierwszą, możesz użyć narzędzia:

dsufac.Do(() => WriteToConsoleWithSomethingExtra("Test")); 
1

Przez jakiś czas robiłem coś takiego w aplikacji Silverlight. Teraz, gdy działa, część z niego pęka.
Dzieje się tak w Silverlight okna potomnego:

(my object context).SaveChanges(() => ChangesSaved()); 

private void ChagngesSaved() 
{ 
    DialogResult = true: // is supposed to close the child window. line gets hit, does not close 
} 
Powiązane problemy