2010-06-27 9 views
10

zu deklarieren Ich habe ein Benutzersteuerelement, das mit fileupload befasst. Ich habe einen Delegaten wie folgt definiertWie generische Ereignisse für generische Delegaten in C#

public delegate void FileUploadSuccess<T>(T value,FileUploadType F) 

Wert kann eine Zeichenfolge sowie Byte-Array sein. FileUploadType ist eine Enumeration, die angibt, welcher Dateityp hochgeladen wurde.

Jetzt habe ich ein Ereignis in usercontrol deklariert, um dies zu erhöhen.

public event FileUploadSuccess<string> successString; //In case I want a file name 

public event FileUploadSuccess<Byte[]> successStringImage; // In case I want a byte[] of uploaded image 

Was war ich ein generisches Ereignis

public event FileUploadSuccess<T> successString. 

Antwort

14

Außer als Teil der generischen Typen (d

class Foo<T> { public event SomeEventType<T> SomeEventName; } 

) gibt es nicht so etwas wie allgemeine Eigenschaften, Felder, Ereignisse, Indexer oder Operatoren (nur generische Typen und generische Methoden). Kann der enthaltende Typ hier generisch sein?

+0

+1 , eine vollständige Antwort. –

4

Für die Außenwelt, ein Ereignis in vielerlei Hinsicht sieht aus wie ein Feld der Klasse wollte. Genauso wie Sie einen offenen generischen Typ nicht verwenden können, um ein Feld zu deklarieren, können Sie keinen offenen generischen Typ verwenden, um ein Ereignis zu deklarieren.

Wenn Sie den Typ offen lassen, dann müsste der Compiler im Event-Handler kompilieren und Code für jeden möglichen Typ für Ihren generischen Parameter T hinzufügen und entfernen. Ein geschlossener generischer Typ kann nicht JIT-kompiliert werden, da Ihr Ereignis kein eigener Typ ist, sondern Teil eines einschließenden Typs ist.

0

Ich glaube nicht, dass das möglich ist.

Ereignis ist wie eine Instanz eines Delegaten (grob gesagt), und eine Instanz ist eine konkrete Implementierung (einer generischen oder einer nicht-generischen Klasse).

Zum besseren Verständnis von Teilnehmern und Ereignissen können Sie auf this SO Diskussion verweisen.

3

Das ist unmöglich, wenn Sie Ihren Typparameter nicht in einer einschließenden Klasse definieren. Zum Beispiel:

public delegate void FileUploadSuccess<T>(T value, FileUploadType F) 

public class FileUploader<T> 
{ 
    public event FileUploadSuccess<T> FileUploaded; 
} 

Aber das bewegt sich nur das Problem an einem anderen Ort, da jetzt würden Sie zwei Instanzen der FileUploader Klasse deklarieren müssen:

FileUploader<string> stringUploader = new FileUploader<string>(); 
FileUploader<byte[]> stringUploader = new FileUploader<byte[]>(); 

Das kann nicht sein, was Sie wollen.

1

Warum benötigen Sie ein generisches Ereignis? Kannst du nicht einfach ein normales Ereignis verwenden:

public delegate void FileUploadSuccess(object value); 

und Handler Bei Erfolg

public event FileUploadSuccess Success; 

dann werden Sie den Typ des Objekts wissen übergeben wird:

public void SuccessHandler(object value) 
{ 
    // you know the type of the value being passed here 
} 
+2

Sir, ich wollte es typsicher machen und dachte, wenn Generika helfen könnten. – Rohit