6
votes

C # Réflexion - Modification de la valeur d'un champ d'une variable

J'ai une instance d'une classe, je souhaite modifier un membre de données d'objet de cette instance uniquement avec un autre objet du même type (échange), En raison de mes contraintes de système, je ne peux pas utiliser =, opérateurs nouveaux ou setter.

Fondamentalement, je voudrais changer la valeur d'un champ d'une variable, le champ est un objet contenu dans un autre objet - la variable que j'ai une instance que j'ai.

est-il possible d'utiliser la réflexion? Si oui, quelqu'un peut-il me donner une direction de base?

merci Yoav


2 commentaires

Pouvez-vous partager du code, s'il vous plaît?


La valeur que vous souhaitez modifier une propriété ou un champ est-elle? Si c'est une propriété, connaissez-vous le nom du champ qui en est derrière? - Fondamentalement, si une propriété n'a pas d'accesseur de jeu, vous ne pouvez pas modifier sa valeur (même en utilisant la réflexion), mais s'il y a un champ derrière, même s'il est privé, vous pouvez (généralement) le changer en utilisant la réflexion. Dans certains cas (je ne me souviens de la référence), vous pouvez même refuser l'accès à la réflexion aux champs privés.


3 Réponses :


13
votes

Oui, c'est possible.

En bref, faites quelque chose comme xxx

pour changer la valeur d'un champ caché (protégé / protégé / interne). Utilisez le Fieldinfo.gevalue correspondant (...) à lire; Combinez les deux de manière triviale pour obtenir votre opération d'échange souhaitée.

Ne vous maintenez pas à la reliureFlags (je semble toujours obtenir ces mauvaises tentatives) ou la syntaxe exacte , mais c'est fondamentalement cela.

regarder sur Système. Réflexion pour référence.


1 commentaires

BindingFlags a fière allure mais peut aussi vouloir inclure le public ... BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance



4
votes

Si vous utilisez .NET 3.5, vous pouvez utiliser ma bibliothèque Open-Source, Fasterflect , pour adresser qu'avec le code suivant: xxx

Lorsque vous utilisez Fasterflect, vous n'avez pas à vous soucier de la spécification BindingFlags droite et de l'implication de la performance (comme lors de l'utilisation de la réflexion).


0 commentaires

0
votes

dans VB avec des génériques, mais la gestion des erreurs rudimentaires:

Module somereflectionops
    Function GetFieldValue(Of OBTYPE, FIELDTYPE)(instance As OBTYPE, fieldname As String,  Optional specbindingflags As BindingFlags = BindingFlags.NonPublic Or BindingFlags.Instance) As FIELDTYPE
        Dim ot As Type = GetType(OBTYPE)
        Dim fi As FieldInfo
        Try
            fi = ot.GetField(fieldname, BindingFlags.Default Or specbindingflags)
            If fi Is Nothing Then Return Nothing
            Return fi.GetValue(instance)
        Catch ex As Exception
            Return Nothing
        End Try
    End Function

    Function SetFieldValue(Of OBTYPE, FIELDTYPE)(instance As OBTYPE, fieldname As String, value As FIELDTYPE, Optional specbindingflags As BindingFlags = BindingFlags.NonPublic Or BindingFlags.Instance) As Boolean
        Dim ot As Type = GetType(OBTYPE)
        Dim fi As FieldInfo
        Try
            fi = ot.GetField(fieldname,  BindingFlags.Default Or specbindingflags)
            If fi Is Nothing Then Return false
            fi.SetValue(instance, value)
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function
End Module


0 commentaires