2010-04-15 9 views
3

Je suis en train de d'utiliser la réflexion pour atteindre les objectifs suivants:C# récursive Listes de réflexion et génériques de définir les propriétés par défaut

je besoin d'une méthode où je passe dans un objet et cette méthode récursive instancier l'objet avec les objets enfants et Définissez les propriétés avec des valeurs par défaut. J'ai besoin de l'objet entier instancié allant autant de niveaux que nécessaire.

Cette méthode doit être capable de gérer un objet avec plusieurs propriétés qui seront des listes génériques d'autres objets.

Voici mon exemple de code (je reçois un paramètre exception de non-concordance de comptage lorsque je reçois un objet contenant un List<AnotherSetObjects>:

private void SetPropertyValues(object obj) 
{ 
    PropertyInfo[] properties = obj.GetType().GetProperties(); 

    foreach (PropertyInfo property in properties) 
    { 
     if (property.PropertyType.IsClass && property.PropertyType != typeof(string) && property.PropertyType.FullName.Contains("BusinessObjects")) 
     { 
      Type propType = property.PropertyType; 

      var subObject = Activator.CreateInstance(propType); 
      SetPropertyValues(subObject); 
      property.SetValue(obj, subObject, null); 
     } 
     else if (property.PropertyType == typeof(string)) 
     { 
      property.SetValue(obj, property.Name, null); 
     } 
     else if (property.PropertyType == typeof(DateTime)) 
     { 
      property.SetValue(obj, DateTime.Today, null); 
     } 
     else if (property.PropertyType == typeof(int)) 
     { 
      property.SetValue(obj, 0, null); 
     } 
     else if (property.PropertyType == typeof(decimal)) 
     { 
      property.SetValue(obj, 0, null); 
     } 
    } 
} 

Merci

+0

Il serait utile de savoir quelle ligne vous obtenez l'erreur. En outre, il semble que vous ne créiez que de nouveaux objets pour les propriétés dont le nom contient BusinessObjects, et ce n'est pas clair si c'était votre intention. –

Répondre

0

Ceci est un délicat un :)

Lorsque vous passez votre initialiseur un objet contenant une liste générique de certains types "BusinessObjects" en tant que propriété, cette propriété transmet votre

if (property.PropertyType.IsClass && property.PropertyType != typeof(string) && property.PropertyType.FullName.Contains("BusinessObjects"))

expression

, parce que le type générique instanciée aura un nom comme celui-ci:

System.Collections.Generic.List`1[[ConsoleApplication92.XXXBusinessObjects, ConsoleApplication92, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] 

Il en résulte la méthode d'initialisation étant appelé avec la liste elle-même comme un paramètre. La liste aura un indexeur nommé Item de type SomeBusinessObjects. Cela va également passer la condition ci-dessus, donc vous allez essayer de l'initialiser aussi. Il en résulte est quelque chose comme ceci:

obj.ListProperty.Item = new SomeBusinessObject(); 

alors qu'un indexeur ne pouvait être utilisé dans une initialisation comme celui-ci

obj.ListProperty[0] = new SomeBusinessObject(); 

Cela montre qu'en effet, votre manque un paramètre.

Qu'est-ce que tu vas faire à ce sujet est à vous :)

+0

Voir ma réponse. :) – Nayan

1

Vous pouvez filtrer en vérifiant property.PropertyType.IsGeneric ce qui est vrai pour les conteneurs génériques. Si vous avez besoin, vérifiez également property.PropertyType.IsArray.

En outre, vous pouvez également vouloir éviter les conteneurs non génériques. Dans ce cas, vérifiez que les objets sont des types d'interface de tels conteneurs. Par exemple - IList.

bool isList(object data) 
{ 
    System.Collections.IList list = data as System.Collections.IList; 
    return list != null; 
} 

... 
if (isList(obj)) { 
    //do stuff that take special care of object which is a List 
    //It will be true for generic type lists too! 
} 
+2

OU vous pouvez simplement utiliser l'opérateur "is" de la langue (qui existe dans ce but précis), et éviter un appel de méthode inutile et la comparaison d'égalité. –

Questions connexes