web-dev-qa-db-fra.com

Comment vérifier toutes les propriétés d'un objet, qu'elles soient nulles ou vides?

J'ai un objet, appelons-le ObjectA

et cet objet a 10 propriétés et ce sont toutes des chaînes.

 var myObject = new {Property1="",Property2="",Property3="",Property4="",...}

est-il possible de vérifier si toutes ces propriétés sont nulles ou vides?

Donc, toute méthode intégrée qui renverrait vrai ou faux?

Si l'un quelconque d'entre eux n'est pas nul ou vide, le retour serait faux. Si tous sont vides, il devrait retourner vrai.

L'idée est que je ne veux pas écrire 10 si instruction pour contrôler si ces propriétés sont vides ou nulles.

Merci

58
akd

Vous pouvez le faire en utilisant la réflexion

bool IsAnyNullOrEmpty(object myObject)
{
    foreach(PropertyInfo pi in myObject.GetType().GetProperties())
    {
        if(pi.PropertyType == typeof(string))
        {
            string value = (string)pi.GetValue(myObject);
            if(string.IsNullOrEmpty(value))
            {
                return true;
            }
        }
    }
    return false;
}

Matthew Watson a suggéré une alternative utilisant LINQ:

return myObject.GetType().GetProperties()
    .Where(pi => pi.PropertyType == typeof(string))
    .Select(pi => (string)pi.GetValue(myObject))
    .Any(value => string.IsNullOrEmpty(value));
77
helb

Je suppose que vous voulez vous assurer que toutes les propriétés sont renseignées.

Une meilleure option consiste probablement à placer cette validation dans le constructeur de votre classe et à lancer des exceptions si la validation échoue. De cette façon, vous ne pouvez pas créer une classe invalide. attraper les exceptions et les gérer en conséquence.

La validation courante est un cadre de Nice ( http://fluentvalidation.codeplex.com ) pour effectuer la validation. Exemple:

public class CustomerValidator: AbstractValidator<Customer> 
{
    public CustomerValidator()
    {
        RuleFor(customer => customer.Property1).NotNull();
        RuleFor(customer => customer.Property2).NotNull();
        RuleFor(customer => customer.Property3).NotNull();
    }
}

public class Customer
{
    public Customer(string property1, string property2, string property3)
    {
         Property1  = property1;
         Property2  = property2;
         Property3  = property3;
         new CustomerValidator().ValidateAndThrow();
    }

    public string Property1 {get; set;}
    public string Property2 {get; set;}
    public string Property3 {get; set;}
}

Usage:

 try
 {
     var customer = new Customer("string1", "string", null);
     // logic here
 } catch (ValidationException ex)
 {
     // A validation error occured
 }

PS - Utiliser la réflexion pour ce genre de choses rend votre code plus difficile à lire. Utiliser la validation comme indiqué ci-dessus montre clairement quelles sont vos règles; et vous pouvez facilement les étendre avec d’autres règles.

14
L-Four

Voici

var instOfA = new ObjectA();
bool isAnyPropEmpty = instOfA.GetType().GetProperties()
     .Where(p => p.GetValue(instOfA) is string) // selecting only string props
     .Any(p => string.IsNullOrWhiteSpace((p.GetValue(instOfA) as string)));

et voici la classe

class ObjectA
{
    public string A { get; set; }
    public string B { get; set; }
}
9
Ondrej Janacek

Une façon légèrement différente d'exprimer linq pour voir si toutes les propriétés de chaîne d'un objet sont non nulles et non vides:

public static bool AllStringPropertyValuesAreNonEmpty(object myObject)
{
    var allStringPropertyValues = 
        from   property in myObject.GetType().GetProperties()
        where  property.PropertyType == typeof(string) && property.CanRead
        select (string) property.GetValue(myObject);

    return allStringPropertyValues.All(value => !string.IsNullOrEmpty(value));
}
5
Matthew Watson

Le code suivant renvoie si une propriété n'est pas null.

  return myObject.GetType()
                 .GetProperties() //get all properties on object
                 .Select(pi => pi.GetValue(myObject)) //get value for the propery
                 .Any(value => value != null); // Check if one of the values is not null, if so it returns true.
3
Valeh Mikayilzadeh

pour ce faire, vous pouvez utiliser des méthodes de réflexion et d’extension.

using System.Reflection;
public static class ExtensionMethods
{
    public static bool StringPropertiesEmpty(this object value)
    {
        foreach (PropertyInfo objProp in value.GetType().GetProperties())
        {
            if (objProp.CanRead)
            {
                object val = objProp.GetValue(value, null);
                if (val.GetType() == typeof(string))
                {
                    if (val == "" || val == null)
                    {
                        return true;
                    }
                }
            }
        }
        return false;
    }
}

puis utilisez-le sur n'importe quel objet avec des propriétés de chaîne

test obj = new test();
if (obj.StringPropertiesEmpty() == true)
{
    // some of these string properties are empty or null
}
2
naffy

Notez que si vous avez une hiérarchie structurelle de données et que vous souhaitez tout tester dans cette hiérarchie, vous pouvez utiliser une méthode récursive. Voici un exemple rapide:

static bool AnyNullOrEmpty(object obj) {
  return obj == null
      || obj.ToString() == ""
      || obj.GetType().GetProperties().Any(prop => AnyNullOrEmpty(prop.GetValue(obj)));
}
2
Dax Fohl

Non, je ne pense pas qu'il existe une méthode pour faire exactement cela.

Vous feriez mieux d'écrire une méthode simple qui prend votre objet et renvoie true ou false.

Alternativement, si les propriétés sont toutes identiques, et que vous voulez simplement les analyser et trouver une seule valeur nulle ou vide, peut-être qu'une sorte de collection de chaînes fonctionnerait pour vous?

0
Chanchowancho

Pour vérifier uniquement si toutes les propriétés sont nulles:

bool allPropertiesNull = !myObject.GetType().GetProperties().Any(prop => prop == null);
0
Tessa