2010-07-29 3 views
1

Plutôt que de donner le cas très spécifique (ce que j'ai fait plus tôt), permettez-moi de donner un exemple général. Disons que j'ai une fonction, appelée callingFunction. Il a un paramètre, appelé paramètre. Le paramètre est d'un type inconnu. Disons alors que je souhaite copier ce paramètre, et le renvoyer comme un nouvel objet. Par exemple, dans le code pseudo, quelque chose le long des lignes de ...Comment copier un objet d'un type inconnu sur VB.net?

Function callingFunction(ByVal parameter As Object) As Object 

    Dim newObj As New Object 

    'newObj has the same value as parameter, but is a distinctly different object 
    'with a different reference 

    newObj = parameter 

    return newObj 

End Function 

EDIT: Informations supplémentaires

La première fois que je posté cette question, j'ai reçu qu'une seule réponse - je me suis senti que peut-être que je fait la question trop spécifique. Je suppose que je vais expliquer plus, peut-être que cela aidera. J'ai une page ASP avec 10 tables dessus. J'essaie, en utilisant le code VB derrière, de trouver une solution unique pour ajouter de nouvelles lignes à n'importe quelle table. Lorsque l'utilisateur clique sur un bouton, une fonction générique "ajouter une ligne" doit être appelée.

La difficulté réside dans le fait que je n'ai aucune garantie sur le contenu de n'importe quelle table. Une nouvelle ligne aura le même contenu que la ligne au-dessus, mais étant donné qu'il y a 10 tables, une rangée pourrait contenir n'importe quel nombre d'objets - boîtes de texte, cases à cocher, etc. Donc je veux créer un objet générique du même type que la ligne au-dessus, puis ajoutez-le à une nouvelle cellule, puis à une nouvelle ligne, puis à la table.

Je l'ai testé à fond, et la seule partie de mon code qui échoue réside dans cette génération dynamique d'un type d'objet. D'où la raison pour laquelle j'ai demandé à propos de la copie d'objets. Aucune des solutions affichées jusqu'à présent ne fonctionne correctement, d'ailleurs. Nous vous remercions de votre aide jusqu'à présent, peut-être que cette information supplémentaire vous facilitera la tâche?

Répondre

1

Vous ne pouvez pas le faire en général. Et ce ne sera pas une bonne idée, par exemple, si parameter est d'un type qui implémente le motif singleton. Si parameter est d'un type qui prend en charge la copie, il doit implémenter l'interface ICloneable. Ainsi, votre fonction pourrait ressembler à ceci:

Function MyFunc(ByVal parameter As Object) As Object 
    Dim cloneableObject As ICloneable = TryCast(parameter, ICloneable) 
    If Not cloneableObject Is Nothing Then 
     Return cloneableObject.Clone() 
    Else 
     Return Nothing 
    End If 
End Function 
1

Vous pouvez mettre en œuvre quelque chose comme ceci:

 Dim p1 As Person = New Person("Tim") 
     Dim p2 As Object = CloneObject(p1) 
     Dim sameRef As Boolean = p2 Is p1 'false'    


    Private Function CloneObject(ByVal o As Object) As Object 
     Dim retObject As Object 
     Try 
      Dim objType As Type = o.GetType 
      Dim properties() As Reflection.PropertyInfo = objType.GetProperties 
      retObject = objType.InvokeMember("", System.Reflection.BindingFlags.CreateInstance, Nothing, o, Nothing) 
      For Each propertyInfo As PropertyInfo In properties 
       If (propertyInfo.CanWrite) Then 
        propertyInfo.SetValue(retObject, propertyInfo.GetValue(o, Nothing), Nothing) 
       End If 
      Next 
     Catch ex As Exception 
      retObject = o 
     End Try 

     Return retObject 
     End Function 

     Class Person 
      Private _name As String 
      Public Property Name() As String 
     Get 
      Return _name 
     End Get 
     Set(ByVal value As String) 
      _name = value 
     End Set 
      End Property 
     Public Sub New() 
     End Sub 
     Public Sub New(ByVal name As String) 
     Me.Name = name 
     End Sub 
End Class 
+0

Cela ne fonctionnera que pour certains types d'objets , par exemple ceux qui ne sont composés que de propriétés de types simples. –

+0

Vous avez absolument raison. Mais parce que je ne connais pas son exigence réelle je pensais que cela pourrait être suffisant et lui donne l'indice par où commencer. Je sais que ce n'est qu'un essai/erreur plus ou moins profonde. Quand je serais le «propriétaire» de ces objets, je mettrais en œuvre iClonable ou les rendrait sérialisables. –

+0

pas d'infraction, votre réponse est très bien et peut être suffisant pour l'OP - ou non (tout comme le mien). Nous avons trop peu d'informations pour savoir lequel convient le mieux. –

0

Voici une classe simple qui fonctionnera pour la plupart des objets (suppose au moins .Net 2.0):

Public Class ObjectCloner 
    Public Shared Function Clone(Of T)(ByVal obj As T) As T 
     Using buffer As MemoryStream = New MemoryStream 
      Dim formatter As New BinaryFormatter 
      formatter.Serialize(buffer, obj) 
      buffer.Position = 0 
      Return DirectCast(formatter.Deserialize(buffer), T) 
     End Using 
    End Function 
End Class 
+0

Les objets pour lesquels il ne fonctionnera pas sont des objets qui ne sont pas sérialisables. –

+0

@John - J'ai remarqué cela et cela m'a intrigué. Je pensais que l'attribut Serializable n'était utilisé que par le Serializer Xml. Mais apparemment, le BinaryFormatter l'utilise aussi. –

+0

le XML Serializer ne l'utilise pas du tout. –

Questions connexes