{"id":3232,"date":"2020-07-21T09:45:27","date_gmt":"2020-07-21T07:45:27","guid":{"rendered":"http:\/\/www.capri-soft.de\/blog\/?p=3232"},"modified":"2020-07-23T15:45:21","modified_gmt":"2020-07-23T13:45:21","slug":"c-und-delegaten-func-action-predicate","status":"publish","type":"post","link":"https:\/\/www.capri-soft.de\/blog\/?p=3232","title":{"rendered":"C# und Delegaten, Func, Action, Predicate"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Was sind Delegates?<\/h2>\n\n\n\n<p>Beispiel:<br><code>public delegate string MeinDelegateName(string s);<\/code><\/p>\n\n\n\n<p>Ein Delegate deklariert einen Datentyp (hier MeinDelegateName) anhand einer Funktionssignatur. Eine Funktionssignatur, welche den Aufbau einer Funktion darstellt, sieht folgenderma\u00dfen aus:<br><br><code>R\u00fcckgabewert DelegateName (Argumente)<\/code><br><br>Diesem Datentyp kann nun eine <em><strong>oder mehrere<\/strong><\/em> <strong><em>(siehe +=-Operator)<\/em><\/strong> Funktionen mit genau dieser Funktionssignatur zugewiesen werden, was das Aufrufen dieser Funktionen erm\u00f6glicht, ohne deren Namen zu kennen. Dadurch wird die Implementierung der Funktion von dem aufrufendem Code entkoppelt.<br><br>Ein Verwendungsbeispiel w\u00e4ren EventListener \/ Events, welchen \u00fcber Delegates die Funktion \u00fcbergeben wird, die beim Eintritt des Events aufgerufen werden soll. \u00dcber den += Operator k\u00f6nnen einem Event mehrere Funktionen zugewiesen werden (z.B. bei einem Windows-Fenster das OnLoad-Event). <\/p>\n\n\n\n<p>Bei der Verwendung von Delegates muss also der Delegate-empfangende Code den Namen der Funktion (bzw. Methode) nicht wissen und kann diese trotzdem aufrufen. Delegates anonymisieren also Funktions- bzw. Methodennamen. Ein \u00e4hnlicher Mechanismus f\u00fcr Klassen stellen Interfaces zur Verf\u00fcgung. Interfaces anonymisieren allerdings nicht per se Namen der deklarierten Methoden\/Funktionen sondern lediglich der Klassennamen. W\u00e4re eine Anonymisierung von Funktions- und Methodennamen gew\u00fcnscht, k\u00f6nnten die Delegates in den Interfaces deklariert werden.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Deklaration von Delegate-Typen mit dem normalen Delegate-Schl\u00fcsselwort<\/h2>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ Definition des Delegatentyps SageHalloWeltDelegate:  \n\/\/ Eine Funktionssignatur, welcher ein string \u00fcbergeben\n\/\/ wird und welche einen String zur\u00fcckgibt, wird festgelegt\npublic delegate string SageHalloWeltDelegate(string s); \n\npublic string sageHalloWeltFunktion(string s)\n{\n    Console.Write(&quot;Hallo&quot;);\n    return &quot; Welt&quot;;\n}\n\npublic Program()\n{\n    \/\/ Instanz der Funktion &quot;delegateInstanzDerFkt&quot; mit der \n    \/\/ Funktionssignatur &quot;SageHalloWeltDelegate&quot;\n    SageHalloWeltDelegate delegateInstanzDerFkt = sageHalloWeltFunktion;\n    \n    \/\/ Aufruf der instanzierten Funktion \n    Console.WriteLine(delegateInstanzDerFkt(&quot;Hallo&quot;));\t\t\n}\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">Durch .NET vordefinierte Delegattypen: Action \/ Func \/ Predicate<\/h2>\n\n\n\n<p>&nbsp;.NET enth\u00e4lt jedoch eine Reihe von Delegattypen, die Programmierer verwenden k\u00f6nnen, damit sie keine neuen Typen (wie oben der Typ &#8222;<strong><em>SageHalloWeltDelegate<\/em><\/strong>&#8222;) erstellen m\u00fcssen.&nbsp;Diese Typen lauten&nbsp;<code>Func&lt;&gt;<\/code>,&nbsp;<code>Action&lt;&gt;<\/code>&nbsp;und&nbsp;<code>Predicate&lt;&gt;<\/code>.&nbsp;<br><br>Die Deklarationszeile des Delegate-Typs <br><code>public delegate string SageHalloWeltDelegate(string s);<\/code><br>f\u00e4llt somit weg.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code>Action&lt;&gt;<\/code>&nbsp;wird verwendet, wenn eine Aktion mithilfe der Argumente des Delegaten ausgef\u00fchrt werden muss.&nbsp;Die von dem Typ gekapselte Methode<strong> gibt keinen Wert zur\u00fcck.<\/strong> <br>Die Signatur darf maximal 16 Argumente enthalten.<br><br>Bsp. f\u00fcr eine Action<br><code>Action&lt;string&gt; delegateInstanzDerFkt<\/code> <code>= sageHalloWeltFunktion;<\/code><br><br>Hier w\u00fcrde der Teil &#8220; Welt&#8220; aus dem obigen Beispiel nicht zur\u00fcckgegeben werden.<br><\/li><li><code>Func&lt;&gt;<\/code>&nbsp;wird \u00fcblicherweise verwendet, wenn eine Transformation ausgef\u00fchrt werden muss, Sie also die Argumente des Delegaten in ein anderes Ergebnis transformieren m\u00fcssen.&nbsp;Projektionen sind ein gutes Beispiel.&nbsp;Die von dem Typ gekapselte Methode gibt einen angegebenen Wert zur\u00fcck. <br>Die Signatur darf maximal 16 Argumente enthalten.<br><br>Bsp. f\u00fcr <strong>R\u00fcckgabewert <\/strong>&#8222;string&#8220; und <strong>\u00dcbergabewert <\/strong>&#8222;string&#8220;:<br><code>Func&lt;string, string&gt; delegateInstanzDerFkt<\/code> <code>= sageHalloWeltFunktion;<\/code> <br><br><strong>Der letzte Typparameter<\/strong> der Func-Deklaration<strong> ist jeweils der R\u00fcckgabewert<\/strong>.<br><code>Func&lt;string, string, <strong>int<\/strong>&gt; delegateInstanzDerFkt<\/code> <code>= sageHalloWeltFunktion;<\/code><br>w\u00fcrde einen Integer-Wert zur\u00fcckgeben und ihr w\u00fcrden zwei Strings \u00fcbergeben werden.<br><\/li><li><code>Predicate&lt;&gt;<\/code>&nbsp;wird verwendet, wenn Sie ermitteln m\u00fcssen, ob das Argument die Bedingung des Delegaten erf\u00fcllt.&nbsp;Sie k\u00f6nnen auch die Schreibweise&nbsp;<code>Func&lt;T, bool&gt;<\/code>&nbsp;verwenden. In diesem Fall gibt die Methode einen booleschen Wert zur\u00fcck. <br>Predicates werden meistens bei LINQ verwendet, wenn man zum Beispiel in Collections oder Listen etwas suchen m\u00f6chte. Meistens wird Predicate dann als LAMBDA-Ausdruck geschrieben. <br>Die Signatur darf maximal 16 Argumente enthalten.<br><br><code>Func&lt;string, bool&gt; delegateInstanzDerFkt<\/code> <code>= sageHalloWeltFunktion;<\/code><br>ist also \u00e4quivalent mit<br><code>Predicate&lt;string&gt;<\/code> <code>delegateInstanzDerFkt<\/code> <code>= sageHalloWeltFunktion;<\/code><br>und w\u00fcrde mit dem obigen Beispiel zu einem Fehler f\u00fchren, da die Methode sageHalloWeltFunktion einen String zur\u00fcckgibt.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Konvertieren von Lamda-Ausr\u00fccken in Delegateinstanzen<\/h2>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ Berechne quadrat\nFunc&lt;int, int&gt; square = x =&gt; x * x; \nConsole.WriteLine(square(5));\n\n\/\/ Konkateniere String\nFunc&lt;string, string, string&gt; concat = (a,b) =&gt; a + &quot; &quot; + b;\nconcat(&quot;Hello&quot;, &quot;World&quot;);\n\n\/\/ Einzelne Action wird ohne \u00dcbergabeparameter (R\u00fcckgabe hat sie nicht)\nAction line = () =&gt; Console.WriteLine(&quot;Hello world!&quot;);\nline();\n\n\/\/ Einzelne Action wird ohne \u00dcbergabeparameter (R\u00fcckgabe hat sie nicht)\nAction line = text =&gt; Console.WriteLine(text);\nline(&quot;Hello world!&quot;);\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">Example:<\/h2>\n\n\n\n<figure><iframe loading=\"lazy\" width=\"100%\" height=\"475\" src=\"https:\/\/dotnetfiddle.net\/Widget\/1ndzmF\"><\/iframe><\/figure>\n\n\n\n<p><\/p>\n<iframe src=\"http:\/\/www.facebook.com\/plugins\/like.php?href=https%3A%2F%2Fwww.capri-soft.de%2Fblog%2F%3Fp%3D3232&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light\" scrolling=\"no\" frameborder=\"0\" allowTransparency=\"true\" style=\"border:none; overflow:hidden; width:450px;margin-top:5px;\"><\/iframe>","protected":false},"excerpt":{"rendered":"<p>Was sind Delegates? Beispiel:public delegate string MeinDelegateName(string s); Ein Delegate deklariert einen Datentyp (hier MeinDelegateName) anhand einer Funktionssignatur. Eine Funktionssignatur, welche den Aufbau einer Funktion darstellt, sieht folgenderma\u00dfen aus: R\u00fcckgabewert DelegateName (Argumente) Diesem Datentyp kann nun eine oder mehrere (siehe +=-Operator) Funktionen mit genau dieser Funktionssignatur zugewiesen werden, was das Aufrufen dieser Funktionen erm\u00f6glicht, ohne &hellip; <a href=\"https:\/\/www.capri-soft.de\/blog\/?p=3232\" class=\"more-link\"><span class=\"screen-reader-text\">C# und Delegaten, Func, Action, Predicate<\/span> weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[4,33],"tags":[133,131,132,105,130,134,135],"class_list":["post-3232","post","type-post","status-publish","format-standard","hentry","category-net","category-c","tag-action","tag-delegates","tag-func","tag-c","tag-delegate","tag-predicate","tag-predicates"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p4yGeN-Q8","jetpack_likes_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3232","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3232"}],"version-history":[{"count":19,"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3232\/revisions"}],"predecessor-version":[{"id":3252,"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3232\/revisions\/3252"}],"wp:attachment":[{"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3232"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3232"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3232"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}