165 votes

C# Interroger les propriétés d'une classe

Je suis actuellement en train de définir toutes les valeurs de mon objet de classe Record .

Voici le code que j'utilise pour remplir l'enregistrement en ce moment, propriété par propriété.

// Loop through each field in the result set
for (int i = 0; i <= resultItems.Length; i++)
{

    Record newRecord = new Record()
    {
            itemtype =   resultItems[i - (fieldCount - 0)],
            itemdesc =   resultItems[i - (fieldCount - 1)],
            prodcode =   resultItems[i - (fieldCount - 2)],
            proddesc =   resultItems[i - (fieldCount - 3)],
            curstat =    resultItems[i - (fieldCount -4)],
            totfree =    resultItems[i - (fieldCount -5)],
            totphys =    resultItems[i - (fieldCount -6)],
            pcolgroup =  resultItems[i - (fieldCount -7)],
            scolgroup =  resultItems[i - (fieldCount -8)],
            totpo =      resultItems[i - (fieldCount - 9)],
            totso =      resultItems[i - (fieldCount - 10)],
            quality =    resultItems[i - (fieldCount - 11)],
            statusdesc = resultItems[i - (fieldCount - 12)],
            groupcode =  resultItems[i - (fieldCount - 13)],
            qualitydes = resultItems[i - (fieldCount - 14)],
            pcoldesc =   resultItems[i - (fieldCount - 15)],
            scoldesc =   resultItems[i - (fieldCount - 16)],
            pgroupdesc = resultItems[i - (fieldCount - 17)],
    };
}

Puis-je itérer à travers chacune des propriétés de façon dynamique sans coder en dur tous les noms de propriétés ?

Quelque chose comme ça :

// Create new Record instance
Record newRecord = new Record();

for (int e = 0; e < propertyCount.Length - 1; e++)
{
    newRecord[fieldname] = resultItems[i - (fieldCount - e)];
}

2 votes

Avez-vous essayé Reflection ? stackoverflow.com/questions/997747/

1 votes

Veuillez consulter ce lien stackoverflow.com/questions/721441/

0 votes

Pourriez-vous expliquer où et comment vous souhaitez maintenir la relation entre une propriété et l'index dans le tableau resultItems ?

312voto

Samuel Slade Points 3910

Vous pouvez éventuellement utiliser Reflection pour ce faire. D'après ce que je comprends, vous pourriez énumérer les propriétés de votre classe et définir les valeurs. Il vous faudrait cependant essayer et vous assurer que vous comprenez l'ordre des propriétés. Consultez le document suivant Documentation MSDN pour plus d'informations sur cette approche.

Pour un indice, vous pourriez éventuellement faire quelque chose comme :

Record record = new Record();

PropertyInfo[] properties = typeof(Record).GetProperties();
foreach (PropertyInfo property in properties)
{
    property.SetValue(record, value);
}

value est la valeur dans laquelle vous voulez écrire (donc de votre resultItems ).

1 votes

Et si je veux utiliser propriété.Getvalue(someOtherClassObjectHavingExacltySameProperties) au lieu d'un valeur ? ( J'ai essayé ceci property ?.SetValue(objAppointment, property.GetValue(temp)) ; mais ça me donne, {"L'objet ne correspond pas au type de cible."} )

0 votes

@MalikAsif Je ne suis pas sûr de bien comprendre, mais il semble que vous essayez de charger une propriété d'un type différent. Si vous posez une question sur SO avec un exemple et que vous le liez ici, je jetterai un coup d'œil pour vous.

3 votes

C'est un sauveur de vie absolu - merci ! J'itère à travers toutes les propriétés de classe pour vérifier que j'ai une valeur (avant de l'écrire en XML).

20voto

jgauffin Points 51913
// the index of each item in fieldNames must correspond to 
// the correct index in resultItems
var fieldnames = new []{"itemtype", "etc etc "};

for (int e = 0; e < fieldNames.Length - 1; e++)
{
    newRecord
       .GetType()
       .GetProperty(fieldNames[e])
       .SetValue(newRecord, resultItems[e]);
}

2 votes

Cela semble bien, mais j'espérais pouvoir le faire dynamiquement, plutôt que de coder en dur les noms de champs. Est-ce possible ? Merci

0 votes

Il semble également que le GetProperty n'est pas disponible pour mon instance de classe. :/

0 votes

Non, il doit y avoir une correspondance quelque part entre les index resultItem et les noms de propriétés.

3voto

rich.okelly Points 24144

Oui, vous pouvez créer un indexeur sur votre classe Record qui fait correspondre le nom de la propriété à la propriété correcte. Cela permettrait de conserver toutes les liaisons du nom de la propriété à la propriété en un seul endroit, par exemple :

public class Record
{
    public string ItemType { get; set; }

    public string this[string propertyName]
    {
        set
        {
            switch (propertyName)
            {
                case "itemType":
                    ItemType = value;
                    break;
                    // etc
            }   
        }
    }
}

Sinon, comme d'autres l'ont mentionné, utilisez la réflexion.

3voto

BheeMa Points 426

J'ai essayé ce que Samuel Slade a suggéré. Ça n'a pas marché pour moi. Le site PropertyInfo était vide. J'ai donc essayé ce qui suit et cela a fonctionné pour moi.

    Type type = typeof(Record);
    FieldInfo[] properties = type.GetFields();
    foreach (FieldInfo property in properties) {
       Debug.LogError(property.Name);
    }

3 votes

C'est parce que votre type n'a que des champs et non des propriétés !

0 votes

Et si nous devions obtenir les valeurs des propriétés au lieu de les définir ?

2voto

Franco Canova Points 1

Ajouter à Samuel Slade réponse pour ceux qui choisissent cette approche (qui est excellente). Prenez en considération deux choses :

  1. GetProperties() vous donne uniquement une liste des propriétés PUBLIQUES de votre classe. (les propriétés PRIVATE ne seront pas incluses).
  2. Vous devez savoir que chaque propriété sur laquelle vous appelez SetValue() doit avoir une méthode setter pour le faire, sinon une ArgumentException sera levée (c'est-à-dire : "L'accesseur set de la propriété n'est pas trouvé").

Cela dit, il faut faire très attention aux propriétés sans méthode setter comme ci-dessous :

public string Username { get; set; }
public bool HasCar
    {
        get
        {
            return this.Car != null;
        }
    }

Ici, la première propriété pourra être définie à la valeur spécifiée, mais pas la seconde, car elle n'a pas de méthode setter. Ce que je fais pour résoudre ce problème est d'utiliser GetSetMethod() sur les propriétés pour distinguer celles qui n'ont pas de méthode de paramétrage comme ci-dessous :

var properties = this.GetType().GetProperties();
foreach(var prop in properties)
{
    if(prop.GetSetMethod() != null) {
        prop.SetValue(this, null);
    };
}

J'espère que ce commentaire vous fera gagner du temps !

Cheers

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X