2010-06-02 10 views
5

Frage zu stellen: Ich habe eine generische Funktion aufgerufen werden soll, wie folgt definiert:eine generische Funktion in VB.NET/C#

 Public Shared Function DeserializeFromXML(Of T)(Optional ByRef strFileNameAndPath As String = Nothing) As T 

Nun, wenn ich es nennen, wollte ich es mit einem der Varianten unten zu tun :

Dim x As New XMLserialization.cConfiguration 
x = XMLserialization.XMLserializeLDAPconfig.DeserializeFromXML(Of x)() 
x = XMLserialization.XMLserializeLDAPconfig.DeserializeFromXML(GetType(x))() 
x = XMLserialization.XMLserializeLDAPconfig.DeserializeFromXML(Of GetType(x))() 

Aber es funktioniert nicht. Ich finde es sehr ärgerlich und nicht lesbar mit

x = XMLserialization.XMLserializeLDAPconfig.DeserializeFromXML(Of XMLserialization.cConfiguration)() 

geben Gibt es eine Möglichkeit, eine generische Funktion aufrufen, indem sie die Art von der Instanz zu bekommen?

Antwort

2

Nur mit den Methoden des Namespace System.Reflection, die es wirklich nicht wert für die Mühe ist, die Sie versuchen zu speichern.

1

Der Typ einer generischen Methode wird zur Kompilierzeit festgelegt, weshalb Sie sie nicht mithilfe einer Variablen festlegen können. Dies ist ein wesentlicher Unterschied zwischen generischer Programmierung und Typreflexion.

3

Generika und Reflexion machen sehr schlechte Freunde. Sie können jedoch dies über MakeGenericMethod tun. Das wird jedoch hart und hässlich.

Seit XmlSerializer basiert auf Type Beispiel - ich würde die Dinge umkehren: habe den wirklich Code Type basiert, und rufen Sie in die von der flachen generischen Version; Beispiel in C#:

public T DeserializeFromXML<T>(string path) { 
    return (T)DeserializeFromXML(typeof(T), path); 
} 
public object DeserializeFromXML(Type type, string path) { 
    //TODO: real code 
} 
2

Es klingt für mich wie Sie einen kürzeren Alias ​​für Ihre XMLserialization.cConfiguration Typ erstellen möchten. Versuchen Sie, die Imports Anweisung, dies zu erreichen: [. Dadurch wird die Frage beantwortet, wie gefragt, nicht unbedingt Ihr größeres Problem zu lösen]

' at the top of the file 
Imports C = XMLserialization.cConfiguration 

' somewhere in the body of the file 
Dim x = XMLserialization.XMLserializeLDAPconfig.DeserializeFromXML(Of C)() 
0

Um zu vermeiden, die Of cConfiguration benötigt werden Sie könnten ein ignoriert umfassen ByVal Configuration As T in der generischen Methode.

Dann könnte man sagen

x = DeserializeFromXML(x) 

Aber @ Antwort DanTao das ist wahrscheinlich besser als meine, wenn Sie eine Anwendung für die Configuration Parameter finden.

1

Es gibt einen guten Grund, warum Sie das nicht einfach in Code tun können und warum die Reflexion ist so viel zusätzliche Arbeit: Generika sind alle über Art zu bewahren, so dass Sie einen List(Of Integer) anstelle eines List(Of Object) haben und werfen müssen/boxen Sie alles und verbessern Sie die Code-Wartbarkeit, indem Sie eine starke Typisierung durch den Code beibehalten (so erhalten Sie weniger Laufzeit-Cast- und Type-Exceptions).

Generika sind wirklich Kompilierzeit. Sie können den angegebenen Typ aufschieben, sodass der generische Code wiederverwendet werden kann oder den Typ hat, der von einer anderen Assembly angegeben wurde.

Ihre Deserialisierung ist jedoch Laufzeit - Sie wissen nicht, welchen Typ Sie haben, wenn Sie den Code schreiben, weshalb Sie eine Variable benötigen, um den Typ zu halten.In diesem Fall gibt es keinen wirklichen Vorteil für den generischen Code - Ihre Serialisierungskosten sind um Größenordnungen höher als die Boxing-Kosten und es gibt keinen Vorteil für die Code-Wartbarkeit für das stark typisierte Ergebnis, da Sie immer noch nicht wissen, was Es ist zur Kompilierzeit.

Kurz gesagt, diese schwer zu sein, ist Art und Weise .Net Ihnen zu sagen, Ihre ursprünglichen Annahmen zu überprüfen - ändern Sie Ihre Methode:

Public Shared Function DeserializeFromXML(Optional ByRef strFileNameAndPath As String = Nothing) As Object 

Und dann werfen Sie Ihr Ergebnis von Objekt zu Ihrer XMLserialization.cConfiguration Klasse.

Verwandte Themen