Laissez-nous commencer par une définition de classe pour l'exemple de l'exemple: supposons maintenant que j'ai une liste personnes contenant 3 objets: p> string[] members = new string[] { "FirstName", "LastName", "Age", "Grade" };
foreach (string member in members)
{
if (people.Select(p => p.**member**).Distinct().Count() == 1)
unionMan.**member** = people[0].**member**;
}
3 Réponses :
Votre dernière idée me semble bon, quelque chose comme ceci: quelques observations: p> Donc, la personne de la classe ressemblerait à ceci: p>
Excellent point sur le constructeur par défaut. Y a-t-il une raison d'utiliser PropertyInfo.GetGetMethod () CODE> et PropertyInfo.GetSetMethod () CODE> Over PropertyInfo.getvalue () Code> et PropriétéInfo. SETVALUE () CODE>? Sinon, je pense que ce dernier est un peu moins verbeux.
@Jonsenchyna: J'ai simplement oublié ces shourtuts: p merci pour l'indice;)
Ah oui, c'est simplement un exemple de classe que j'ai jeté ensemble dans l'éditeur de la présente, l'objet réel a en effet un constructeur qui définit chaque membre à son état "invalide" par défaut. En ce qui concerne les propriétés VS membres, l'objet réel que je travaille est défini dans une assemblée externe que je ne puisse pas changer en raison de problèmes de dépendance.
Je voudrais recommande d'utiliser la réflexion. Vous voudriez obtenir le Fieldinfo (ou Par exemple: P> Type personType = typeof(Person);
foreach(string member in members)
{ // Get Fields via Reflection
FieldInfo field = peopleType.GetField(member);
if(field != null)
{
if (people.Select(p => field.GetValue(p, null) ).Distinct().Count() == 1)
{
field.SetValue(unionMan, field.GetValue(people[0], null), null);
}
}
else // If member is not a field, check if it's a property instead
{ // Get Properties via Reflection
PropertyInfo prop = peopleType.GetProperty(member);
if(prop != null)
{
if (people.Select(p => prop.GetValue(p, null) ).Distinct().Count() == 1)
{
prop.SetValue(unionMan, prop.GetValue(people[0], null), null);
}
}
}
}
Ce n'est en effet qu'un sous-ensemble des propriétés. En ce qui concerne les valeurs non valides, cela se fait déjà dans le constructeur alors que je l'ai signalé dans mon commentaire à Digemall il y a des moments. J'aime votre recommandation de stocker la propriétéInfo cependant, merci!
Il est inefficace de faire une distinction de toutes les valeurs simplement pour compter les membres distincts. Vous avez un scénario de raccourci dans lequel la recherche d'une valeur dans tout em> des éléments suivants n'a pas la même valeur que le premier élément de l'élément signifie que vous avez un état invalide pour cette colonne. quelque chose comme Cela devrait fonctionner, bien que davantage de travaux devraient être effectués si l'un des membres est des matrices, une évaluation récursive ou une autre logique plus complexe (note que je n'ai pas testé cela): P> public static T UnionCombine<T>(this IEnumerable<T> values) where T : new() {
var newItem = new T();
var properties = typeof(T).GetProperties();
for (var prop in properties) {
var pValueFirst = prop.GetValue(values.First(), null);
var useDefaultValue = values.Skip(1).Any(v=>!(Object.Equals(pValueFirst, prop.GetValue(v, null))));
if (!useDefaultValue) prop.SetValue(newItem, pValueFirst, null);
}
return newItem;
}
+1 Super idée de ne pas utiliser distinct mais juste vérifier sur la première valeur :)
+1 très élégant. Vous avez juste oublié d'ajouter le mot ceci code> à votre déclaration de paramètre.
Pas de tableaux, Seulement des types de données simples int code> et string code>. +1 pour l'observation que distincte () code> n'est pas nécessaire dans ce cas.
Eh bien, l'idée de votre seconde devrait fonctionner, mais vraiment pas avec le code indiqué! À propos, vous devez avoir un constructeur par défaut pour la personne avec vos valeurs "non valides".