2012-04-07 8 views
1

Ich möchte eine Methode implementieren, die Sachen in meiner benutzerdefinierten Klasse findet. Es sollte funktionieren wie generische Sammlungen funktionieren - ich übergebe einen Zeiger auf eine Funktion, und die Methode wird alles durchlaufen, was sie suchen muss, wenden Sie diese Funktion an, und wenn sie wahr zurückgibt, geben Sie das gefundene Element zurück.C# -Funktion, die den Zeiger als In-Parameter verwendet, ohne bestimmte Delegattypen zu deklarieren?

Ich würde Funktionszeiger als Parameter übergeben, aber ich möchte Delegatentypen nicht deklarieren.

weiß, dass ich mich so etwas wie tun:

delegate bool Foo(MyClass) 
MyClass MyMethod(Foo x) 
{...} 

Und ich weiß, dass ich etwas tun kann:

MyClass MyMethod(Func<MyClass,bool> x) 

Aber kann ich es tun, ohne einen Delegattyp zu deklarieren und ohne eingebaute Verwendung in Sachen wie Func <> die Grenzen hat, wie viele Parameter ich haben kann (im Falle von Func, eine ...)

+0

Nun, vielleicht können Sie Funktion mit einem Objekt-Array haben? –

+0

In .NET 3.5 kann 'Func' mehr als einen Parameter haben. http://msdn.microsoft.com/en-us/library/bb549151(v=vs.90).aspx siehe: http://i.imgur.com/yQIaf.png – Cheeso

+0

Danke. Gibt es eine Möglichkeit, den Delegattyp in der Methodendeklaration zu deklarieren, oder muss ich Func <> verwenden? – Istrebitel

Antwort

0

Sie nur delegieren wenn Sie möchten, verwenden können, obwohl es ein bisschen old school :)

public void TestInvokeDelegate() 
{ 
    InvokeDelegate(new TestDelegate(ShowMessage), "hello"); 
} 

public void InvokeDelegate(TestDelegate del, string message) 
{ 
    del(message); 
} 

public delegate void TestDelegate(string message); 

public void ShowMessage(string message) 
{ 
    Debug.WriteLine(message); 
} 
+0

Ich möchte öffentliche void InvokeDelegate (TestDelegate del, String-Nachricht) ohne die Notwendigkeit, TestDelegate zu deklarieren - ich will "Funktion InvokeDelegate nimmt einen Funktionszeiger, der String nimmt und void zurückgibt" - kann ich es tun? – Istrebitel

+0

Nein, Sie können es nicht tun, Sie denken an C++. Was ist das Problem mit Func <> oder Action <>? – Phil

+0

Es gibt keine, ich fragte nur, ob ich es tun kann oder nicht :) – Istrebitel

0

Sie können immer in eineübergeben 0 und DynamicInvoke auf ihn nennen:

MyClass MyMethod(Delegate x) { 
    // ... 
    x.DynamicInvoke(....); 
    // ... 
} 
+0

Mit anderen Worten: Delegate stellt eine generische Methode dar, mit der ich alle Parameter übergeben und am Ende jeden Wert erwarten kann. Es ist wie "Objekt" von Funktionen? – Istrebitel

0

Es ist wie Sie die Visitor pattern zu implementieren versuchen, sieht . In diesem Fall haben Besuchsmethoden in der Regel nur einen Parameter - die zu besuchende Instanz. Wenn zusätzliche Argumente herumgereicht werden, verbirgt sich die Verwendung des Musters und macht es schwieriger, darüber nachzudenken. This article zeigt Ihnen eine Möglichkeit, es in C# zu implementieren.

Der Schlüssel ist das Erstellen einer Besucherklasse, die alle Parameter einkapselt, die den Besuchsprozess beeinflussen. Auf diese Weise müssen Sie in der Besuchsmethode nichts anderes als ein Objekt übergeben - alles andere lebt in Instanzfeldern.

Wenn Sie jedoch einige zusätzliche Parameter in der Methode übergeben möchten und nicht wissen, welchen Typ sie haben können, gibt es Möglichkeiten, dies zu tun. Mehr oder weniger Standard-Ansatz in .NET-Welt ist einen Delegaten ohne Rückgabewert und mit einzelnen Parametern des Typs zu verwenden, object, würde das Beispiel ParameterizedThreadStart delegate sein:

public delegate void ParameterizedThreadStart(
    Object obj 
) 

So kann man nur einen Parameter in den Delegierten zu übergeben bekommen , aber es könnte alles sein - eine Instanz einer Klasse, ein Array oder null, wenn Sie am Ende keine zusätzlichen Argumente benötigen. Der Nachteil dieses Ansatzes ist, dass Typcasting erforderlich ist, was zu Laufzeitfehlern führen kann.

+0

Nein, das ist nicht was ich will, aber danke für wertvolle Informationen! – Istrebitel

+0

@Istrebitel: Nun, die Sache, die du im ersten Absatz beschreibst, ist * genau *, wofür das Besuchermuster erfunden wurde, also solltest du es wahrscheinlich untersuchen – Dyppl

+0

Nein, eigentlich brauche ich nur eine Suchfunktion für mein benutzerdefiniertes TreeView Durchsucht die Tags der Treenodes. Also möchte ich einen Funktionszeiger an es übergeben, und es wird diese Funktion auf jeden treenode anwenden, bis True gefunden wird. Der Parameter für die Methode ist TreeNode, der überprüft wird. Nun wollte ich nur wissen, ob ich dies tun kann, ohne einen Delegattyp zu deklarieren – Istrebitel

Verwandte Themen