Wie überprüfe ich alle Eigenschaften eines Objekts, ob null oder leer?


73

Ich habe ein Objekt, nennen wir es ObjectA

und dieses Objekt hat 10 Eigenschaften und das sind alles Zeichenfolgen.

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

Gibt es überhaupt eine Möglichkeit zu überprüfen, ob alle diese Eigenschaften null oder leer sind?

Also eine eingebaute Methode, die wahr oder falsch zurückgeben würde?

Wenn einer von ihnen nicht null oder leer ist, wäre die Rückgabe falsch. Wenn alle leer sind, sollte true zurückgegeben werden.

Die Idee ist, dass ich keine 10 if-Anweisung schreiben möchte, um zu steuern, ob diese Eigenschaften leer oder null sind.

Vielen Dank


4
Versuchen Sie es mit Reflexion.
Ondrej Janacek

1
Reflexion, aber fragen Sie sich ... Ist diese Datenstruktur ein guter Ansatz? Scheint , wie myObjectist wirklich nur ein Array.
CodingIntrigue

2
Die Idee in der Webentwicklung ist, dass ich ein Ansichtsmodell (Suchfilter) habe und wenn sie alle Filter leer lassen, gibt die linq-Anweisung das gesamte Ergebnis aus der Datenbank zurück. Ich kam irgendwie auf die Idee, dass der Filter nicht angewendet werden sollte, wenn diese Filter vom Ansichtsmodell leer zurückgegeben werden. Aber 10 zu schreiben, wenn es sonst überhaupt nicht gut klingt.
Akd

Antworten:


103

Sie können dies mit Reflection tun

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 schlug eine Alternative mit LINQ vor:

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

Wenn Sie eine ID-Eigenschaft haben oder etwas, das ausgeschlossen werden muss, können Sie Folgendes überprüfen: if (pi.Name.Equals ("InfoID") || pi.Name.Equals ("EmployeeID") || pi.Name.Equals ("LastUpdated" ")) fortsetzen;
Kremena Lalova

16

Ich nehme an, Sie möchten sicherstellen, dass alle Eigenschaften ausgefüllt sind.

Eine bessere Option besteht wahrscheinlich darin, diese Validierung in den Konstruktor Ihrer Klasse einzufügen und Ausnahmen auszulösen, wenn die Validierung fehlschlägt. Auf diese Weise können Sie keine ungültige Klasse erstellen. Ausnahmen abfangen und entsprechend behandeln.

Die fließende Validierung ist ein nützliches Framework ( http://fluentvalidation.codeplex.com ) für die Validierung. Beispiel:

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;}
}

Verwendung:

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

PS: Die Verwendung von Reflektion für solche Dinge macht das Lesen Ihres Codes nur schwieriger. Wenn Sie die oben gezeigte Validierung verwenden, wird deutlich, wie Ihre Regeln lauten. und Sie können sie leicht mit anderen Regeln erweitern.


10

Bitte schön

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)));

und hier ist die Klasse

class ObjectA
{
    public string A { get; set; }
    public string B { get; set; }
}

1
Es heißt, dass p.GetValue (myObj) an beiden Stellen nicht aufgelöst werden kann.
Akd

Versuchen Sie, meine Antwort zu kopieren und einzufügen. Die Klasse selbst und dann den Code und führen Sie ihn bitte erneut aus.
Ondrej Janacek

1
Bitte, wenn Sie meine Antwort ablehnen, sagen Sie mir warum. Wie könnte ich sie sonst verbessern, wenn ich nicht weiß, warum sie herabgestuft werden?
Ondrej Janacek

Ich habe Ihre Antwort nicht abgelehnt, aber Ihre Antwort funktioniert bei mir nicht. Das Objekt, von dem ich spreche, ist etwas ActionResult SearchResult (MyObjectViewModel myObj) {}
akd

2
Bearbeiten Sie Ihre Fragen und fügen Sie dort den genauen Code hinzu, den Sie versuchen, und erklären Sie bitte deutlich, welchen Fehler Sie erhalten. Ich habe eine allgemeine Antwort gepostet, weil Sie eine allgemeine Frage gestellt haben. In Ihrer Frage gibt es nichts über Ansichten und Controller.
Ondrej Janacek

6

Der folgende Code wird zurückgegeben, wenn eine Eigenschaft nicht null ist.

  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.

5

Eine etwas andere Art, die Linq auszudrücken, um festzustellen, ob alle Zeichenfolgeeigenschaften eines Objekts nicht null und nicht leer sind:

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));
}

Dies funktioniert, aber wenn das Objekt eine Eigenschaft hat ID, kann ich IDs erhalten, deren Eigenschaften null oder leer sind?
Shaijut

@stom Sie können Filter hinzufügen, um den Nameund den Wert zu überprüfen .
Matthew Watson

Danke, ich habe nicht verstanden, welche Filter du meinst, aber ich werde etwas recherchieren.
Shaijut

sich erinnern, Eigentum zu geben bekommen; einstellen; oder die GetProperties funktionieren nicht, siehe stackoverflow.com/questions/7838189/…
yu yang Jian

3

Hinweis: Wenn Sie eine Datenstrukturhierarchie haben und alles in dieser Hierarchie testen möchten, können Sie eine rekursive Methode verwenden. Hier ist ein kurzes Beispiel:

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

2

Sie können dazu Reflektions- und Erweiterungsmethoden verwenden.

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;
    }
}

Verwenden Sie es dann für jedes Objekt mit Zeichenfolgeeigenschaften

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

1

So überprüfen Sie nur, ob alle Eigenschaften null sind:

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

0

Nein, ich glaube nicht, dass es eine Methode gibt, um genau das zu tun.

Am besten schreiben Sie eine einfache Methode, die Ihr Objekt nimmt und true oder false zurückgibt.

Wenn die Eigenschaften alle gleich sind und Sie sie nur analysieren und eine einzelne Null oder eine leere finden möchten, funktioniert möglicherweise eine Art Sammlung von Zeichenfolgen für Sie?

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.