6
votes

Est-il possible de modifier l'attribut d'une propriété au moment de l'exécution?

est-il possible de modifier l'attribut d'une propriété au moment de l'exécution?

Disons que j'ai une classe: xxx

est un moyen de faire cela? < / p> xxx


5 commentaires

Pourquoi? C'est peut-être préférable de définir une valeur sur cette propriété afin qu'elle ne fasse pas ce que vous voulez. Ou est-ce pour la sérialisation?


À droite, alors qu'essayez-vous de faire? Arrêter un champ donné d'être sérialisé? Ou le rendre sérialisé sur certaines fois? Si c'est l'un ou l'autre de ceux-ci, vous pouvez toujours avoir deux champs, un avec '[non-séralisée]', qui ne vous a pas été sauvé, et lorsque vous décidez que cela devrait, vous définissez «l'autre». Mais nous aurons besoin d'un peu plus d'informations sur votre raisonnement exact pour cela.


OK, l'utilisateur peut cocher une case à cocher s'il veut que leProperty soit sérialisé ou non. Donc, en fonction de l'entrée de l'utilisateur, l'attribut doit changer.


Hmm. Eh bien, je serai intéressé de voir ce que Marc suggère; Au lieu de cela, comment la sérialisation est-elle faite? Est-ce que c'est personnalisé XML? Ou comptez-vous simplement vous appeler sur le système de sérialisation binaire?


Dans ce cas, je suggère que vous puissiez simplement mettre votre propre attribut dessus et modifier une valeur (dosériense = true); Je ne sais pas avec certitude si cela est possible, mais cela devrait presque certainement être, par réflexion. Je serais intéressé de savoir si Marc Gravell a une meilleure idée cependant.


7 Réponses :


5
votes

Non, cela n'est pas possible. Vous ne pouvez pas modifier les valeurs d'attribut des métadonnées ou des métadonnées en général, à l'exécution

Strictement parlant ce qui précède n'est pas vrai. Certaines API permettent de permettre une génération et une modification de métadonnées. Mais ils sont très spécifiques, (ENC, profilage, débogage) et ne doivent pas être utilisés dans des programmes à usage général.


0 commentaires

2
votes

Cela dépend; D'une perspective de réflexion: non. Vous ne pouvez pas. Mais si vous parlez d'attributs utilisés par system.componentmodel dans des éléments tels que la liaison de données, vous pouvez utiliser Typedescriptor.addattributes code> pour ajouter des attributs supplémentaires. Ou d'autres modèles de clients impliquant des descripteurs personnalisés. Donc, cela dépend du cas d'utilisation.


Dans le cas de la sérialisation XML, il devient plus intéressant. Tout d'abord, nous pouvons utiliser des modèles d'objet amusant: p> xxx pré>

le bool {nom} spécifié {get; définir;} code> motif (avec bool devrait {nom} () code>) est reconnu et utilisé pour contrôler quels éléments à inclure. p>

Une autre alternative consiste à utiliser la CTOR non par défaut: P>

using System;
using System.Xml.Serialization;
public class MyData
{
    [XmlAttribute]
    public int Id { get; set; }
    public string Name { get; set; }

    static void Main()
    {
        var obj = new MyData { Id = 1, Name = "Fred" };

        XmlAttributeOverrides config1 = new XmlAttributeOverrides();
        config1.Add(typeof(MyData),"Name",
            new XmlAttributes { XmlIgnore = true});
        var ser1 = new XmlSerializer(typeof(MyData),config1); 
        ser1.Serialize(Console.Out, obj);
        Console.WriteLine();
        Console.WriteLine();
        XmlAttributeOverrides config2 = new XmlAttributeOverrides();
        config2.Add(typeof(MyData), "Name",
            new XmlAttributes { XmlIgnore = false });
        var ser2 = new XmlSerializer(typeof(MyData), config2);
        ser2.Serialize(Console.Out, obj);
    }
}


2 commentaires

Je parle d'attributs pour inclure / exclure certaines propriétés lors de la sérialisation.


Donc, juste par Addinga Property Nomspecified Le XMLSerializer sait s'il a besoin de sérialiser le nom? Ou je manque quelque chose?



1
votes

Les attributs sont cuits en code au moment de la compilation. La seule façon de définir de nouveaux attributs au moment de l'exécution consiste à générer un nouveau code au moment de l'exécution (à l'aide de la réflexion.emit, par exemple). Mais vous ne pouvez pas modifier les attributs du code existant.


0 commentaires

1
votes

Vous pouvez mettre une variable booléenne dans la classe pour désactiver / activer la propriété au lieu de la désactiver au moment de l'exécution.


0 commentaires


0
votes

On dirait que vous souhaitez envisager d'implémenter ixmlSerializable < / a>


0 commentaires

0
votes

Vous pouvez implémenter idatarrorinfo, puis vérifier la plage de validation de la méthode de validation.

protected override string Validate(string property) {
        Debug.WriteLine(property);
        if (property == nameof(YourProperty)) {
            if (_property > 5) {
                return "_property out of range";
            }
        }
        return base.Validate(property);
    }


0 commentaires