I have the following code that should check if all the properties of class are null. I tried the code below but it didn't work. Why?
You could make a property IsInitialized, that does this internally:
public bool IsInitialized
{
get
{
return this.CellPhone == null && this.Email == null && ...;
}
}
Then just check the property IsInitialized:
if (myUser == null || myUser.IsInitialized)
{ ... }
Another option is the use of reflection to walk over and check all properties, but it seems overkill to me. Also, this gives you the freedom to deviate from the original design (when you choose all properties, except one should be null for example).
//NameSpace
using System.Reflection;
//Definition
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;
}
//Call
bool flag = IsAnyNullOrEmpty(objCampaign.Account);
Related
I'v been playing around with some shorter hand ways of checking multiple nested objects to see if any are null before proceeding. I'm trying to replace the multiple nested if statements into a single statement if possible using Null-conditional Operators.
So far i have something like this:
if ((Object1?.Object2?.Object3?.Object4 != null) ? true : false)
{
...
}
Would the above be effective at identifying if either Object1 2 3 or 4 is null and return a false if so? I'm interested to hear if anyone has any better solutions?
TIA
You don't need to return false or true - boolean condition itself has boolean value:
if (Object1?.Object2?.Object3?.Object4 != null)
This part is a completely valid option for checking nested objects if any of them is null. You can find exactly same example in null-conditional operator documentation:
// null if customers, the first customer, or Orders is null
int? count = customers?[0]?.Orders?.Count();
And explanation:
The last example demonstrates that the null-condition operators are
short-circuiting. If one operation in a chain of conditional member
access and index operation returns null, then the rest of the chain’s
execution stops.
The code
public void Foo()
{
if ((Object1?.Object2?.Object3?.Object4 != null) ? true : false)
{
...
}
}
is logically equivalent to
public void Foo()
{
if ((NullCheck(Object1) != null) ? true : false)
{
...
}
}
private Object4Type NullCheck(Object1Type object1)
{
if(!Object.RefrenceEquals(object1, null)) //This is "Object1?."
{
var tmpObject2 = tmpObject1.Object2;
if(!Object.RefrenceEquals(tmpObject2, null)) //This is "Object2?."
{
var tmpObject3 = tmpObject2.Object3;
if(!Object.RefrenceEquals(tmpObject3, null)) //This is "Object3?."
{
return tmpObject3.Object4;
}
}
}
return default(Object4Type);
}
or if Object4Type is a struct
public void Foo()
{
if ((NullCheck(Object1) != null) ? true : false)
{
...
}
}
private Nullable<Object4Type> NullCheck(Object1Type object1)
{
if(!Object.RefrenceEquals(object1, null)) //This is "Object1?."
{
var tmpObject2 = tmpObject1.Object2;
if(!Object.RefrenceEquals(tmpObject2, null)) //This is "Object2?."
{
var tmpObject3 = tmpObject2.Object3;
if(!Object.RefrenceEquals(tmpObject3, null)) //This is "Object3?."
{
return tmpObject3.Object4;
}
}
}
return default(Nullable<Object4Type>);
}
So your ... will only be run if all objects are not null and if a lower level object is null, the later objects never get evaluated.
What you have is currently the best way to do exactly what you want. I wanted to answer in order to illustrate what's necessary if you don't have access to the latest C# 6 language features. This is the next most developer-friendly way to make the same check in .NET 3.5-4.0:
//boilerplate, off in your extension method library
public static TOut OrDefault<TIn, TOut>(this TIn input,
Func<TIn, TOut> possiblyNullFunc)
{
try { return possiblyNullFunc(input); }
catch (NullReferenceException) //for most reference types
{ return default(TOut); }
catch (InvalidOperationException) //for Nullable<T>
{ return default(TOut); }
}
...
//usage
if (Object1.OrDefault(o=>o.Object2.Object3.Object4) != null)
{
...
}
It functions pretty well, until you try to use InvalidOperationException in your own classes for situations other than null member access.
Still beats the pants off this, especially if you have to make this check a lot:
if(Object1 != null
&& Object1.Object2 != null
&& Object1.Object2.Object3 != null
&& Object1.Object2.Object3.Object4 != null)
{
...
}
I am suffering a weird problem in C# 4.5.
I have this in my model:
private DataMatrix<T> _matrix;
public DataMatrix<T> Matrix
{
get { return _matrix; }
set { _matrix = value; }
}
And I have a property which uses this:
public object SingleElement
{
get
{
if (Matrix == null) return String.Empty;
if (Matrix.ColumnCount >= 1 && Matrix.RowCount >= 1)
{
return Matrix[0, 0];
}
return null;
}
}
When I run it, before calling SingleElement, the Matrix property is null. But it doesn't return String.Empty, it goes to the second if-statement.
That's my Immediate window says:
I'm a bit confused. What did I do wrong?
This is a most likely a broken equality operator (==), which can be reproduced with the following code:
class Foo
{
public static bool operator == (Foo x, Foo y)
{
return false; // probably more complex stuff here in the real code
}
public static bool operator != (Foo x, Foo y)
{
return !(x == y);
}
static void Main()
{
Foo obj = null;
System.Diagnostics.Debugger.Break();
}
// note there are two compiler warnings here about GetHashCode/Equals;
// I am ignoring those for brevity
}
now at the breakpoint in the immediate window:
?obj
null
?(obj==null)
false
Two fixes:
preferred would be to fix the operator, perhaps adding before anything else:
if(ReferenceEquals(x,y)) return true;
if((object)x == null || (object)y == null) return false;
// the rest of the code...
alternative, if you can't edit that type, is to avoid using the operator; consider using ReferenceEquals explicitly in your code, or performing object-based null checks; for example:
if(ReferenceEquals(Matrix, null)) ...
or
if((object)Matrix == null) ...
I have an object lets call it ObjectA
and that object has 10 properties and those are all strings.
var myObject = new {Property1="",Property2="",Property3="",Property4="",...}
is there anyway to check to see whether all these properties are null or empty?
So any built-in method that would return true or false?
If any single of them is not null or empty then the return would be false. If all of them are empty it should return true.
The idea is I do not want to write 10 if statement to control if those properties are empty or null.
Thanks
You can do it using Reflection
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 suggested an alternative using LINQ:
return myObject.GetType().GetProperties()
.Where(pi => pi.PropertyType == typeof(string))
.Select(pi => (string)pi.GetValue(myObject))
.Any(value => string.IsNullOrEmpty(value));
I suppose you want to make sure that all properties are filled in.
A better option is probably by putting this validation in the constructor of your class and throw exceptions if validation fails. That way you cannot create a class that is invalid; catch exceptions and handle them accordingly.
Fluent validation is a nice framework (http://fluentvalidation.codeplex.com) for doing the validation. Example:
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 - Using reflection for this kind of thing just makes your code harder to read. Using validation as shown above makes it explicitly clear what your rules are; and you can easily extend them with other rules.
The following code returns if any property is not null.
return myObject.GetType()
.GetProperties() //get all properties on object
.Select(pi => pi.GetValue(myObject)) //get value for the property
.Any(value => value != null); // Check if one of the values is not null, if so it returns true.
Here you go
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)));
and here's the class
class ObjectA
{
public string A { get; set; }
public string B { get; set; }
}
A slightly different way of expressing the linq to see if all string properties of an object are non null and non empty:
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));
}
Note if you've got a data structural hierarchy and you want to test everything in that hierarchy, then you can use a recursive method. Here's a quick example:
static bool AnyNullOrEmpty(object obj) {
return obj == null
|| obj.ToString() == ""
|| obj.GetType().GetProperties().Any(prop => AnyNullOrEmpty(prop.GetValue(obj)));
}
To only check if all properties are null:
bool allPropertiesNull = !myObject.GetType().GetProperties().Any(prop => prop == null);
you can use reflection and extension methods to do this.
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;
}
}
then use it on any object with string properties
test obj = new test();
if (obj.StringPropertiesEmpty() == true)
{
// some of these string properties are empty or null
}
No, I don't think there is a method to do exactly that.
You'd be best writing a simple method that takes your object and returns true or false.
Alternatively, if the properties are all the same, and you just want to parse through them and find a single null or empty, perhaps some sort of collection of strings would work for you?
You can try the following query :
if the object is "referenceKey" (where few properties may be null )
referenceKey.GetType().GetProperties().Where(x => x.GetValue(referenceKey) == null)
I need to count the properties where the value is set to not Null, so I have used the following query :
var countProvidedReferenceKeys = referenceKey.GetType().GetProperties().Where(x => x.GetValue(referenceKey) != null).Count();
The following overloaded ==operator is part of the Calender class in QL.net
public static bool operator ==(Calendar c1, Calendar c2)
{
return (c1.empty() && c2.empty())
|| (!c1.empty() && !c2.empty() && c1.name() == c2.name());
}
public bool empty() { return (object)calendar == null; }
When I try to access the SouthAfricanCalender property, I receive a System.NullReferenceException : Object reference not set to an instance of an object. which prompted me to dig into the source.
public SouthAfrica SouthAfricanCalender
{
get
{
if (_calender == null)
{
_calender = new SouthAfrica();
}
return _calender;
}
set
{
if (_calender == null)
{
_calender = value;
}
}
}
SouthAfrica _calender;
I have ammended the overload as follows based on the answer here
public static bool operator ==(Calendar c1, Calendar c2)
{
if ( object.ReferenceEquals(c1,c2)) return true;
if ((object)c1 == null || (object)c2 == null) return false;
return (c1.empty() && c2.empty())
|| (!c1.empty() && !c2.empty() && c1.name() == c2.name());
}
My question, have I changed the intent of the original code with my amendment?
Edit: any suggestions on how this can be cleaned up further?
No. You ensure that both are objects, and respond accordingly in the places that they aren't (assuming that ReferenceEquals can handle double null). Then you simply execute the same check. The whole .empty() thing is totally unnecessary, by the way, you already know that it's not null, just return the name comparison.
No, you haven't.
It still checks for equality.
I've defined a C# class with a string member. For all intents an purposes, think of this class as being a subclass of string (except that's not allowed). I'm using it to represent a strongly typed string field that matches a specific format (I've simplified this significantly).
public class field
{
private readonly string m_field;
public field(string init_value)
{
//Check the syntax for errors
if (CheckSyntax(init_value))
{
m_field = init_value;
}
else
{
throw new ArgumentOutOfRangeException();
}
}
public override string ToString()
{
return m_field;
}
}
Now, I want to be able to compare this class directly to any other string (object or literal). Therefore, I implemented the following in the class:
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
return this.m_field == obj.ToString();
}
public override int GetHashCode()
{
return this.m_field.GetHashCode();
}
public static bool operator ==(field x, Object y)
{
if ((object)x == null && y == null)
{
return true;
}
else if ((object)x == null || y == null)
{
return false;
}
else
{
return (x.m_field == y.ToString());
}
}
public static bool operator !=(field x, Object y)
{
return !(x == y);
}
Now when I'm writing a unit test, depending on the order that I'm passing in the arguments to Assert.AreEqual, I get different results:
string valid = "Some String";
field target = new field(valid);
Assert.AreEqual(target, valid); // PASSES
Assert.AreEqual(valid, target); // FAILS
I'm assuming this is because in the first assert, it's calling field.Equals() and in the second it's calling String.Equals(). Obviously I'm approaching this from the wrong angle. Can anyone give me some insight?
One other thing. I can't use a struct here (value type) because in my actual case I'm defining all this in a base class and inheriting from it.
Basically you can't do what you want to - there's no way you can make string recognise your class for equality purposes. You'll never be able to make it reflexive - you'll never be able to make it obey the contract of object.Equals.
I would personally try to redesign it so that you didn't have the validation as part of the type itself - make it part of the relevant properties of the business entities (or whatever they are).
This is described in detail in Effective Java as Item 8: Obey the general contract when overriding equals.
The equals method implements an equivalence relation.
It is Reflexive, Symmetric, Transitive, Consistent, and for any non-null reference x, x.equals(null) must return false. The example cited to break symmetry is similar to yours.
field class is aware of string class, but the built-in string class is not aware of field. This a one-way interoperability, and should be removed.
I would discourage anyone using your field class implicitly as a String, and force this type of usage:
string valid = "Some String";
field target = new field(valid);
Assert.AreEqual(target.toString(), valid);
Assert.AreEqual(valid, target.toString());
Based on everyone's feedback, and my own needs, here's what I'm putting forward as a possible solution (I'm modifying the Equals method as follows):
public override bool Equals(Object obj)
{
if (obj == null)
{
return false;
}
field f = obj as field;
if (f != null)
{
return this == f;
}
else
{
return obj.Equals(this);
}
}
This seems to allow its correct use in dictionary and collection classes that rely on the Equals and GetHashCode methods for determining if the value already exists.
Also, now these both fail:
string valid = "Some String";
field target = new field(valid);
Assert.AreEqual(target, valid); // FAILS
Assert.AreEqual(valid, target); // FAILS
And these both pass:
string valid = "Some String";
field target = new field(valid);
Assert.AreEqual(target.ToString(), valid); // PASSES
Assert.AreEqual(valid, target.ToString()); // PASSES
And these both pass:
field f1 = new field("Some String");
field f2 = new field("Some String");
Assert.AreEqual(f1, f2); // PASSES
Assert.AreEqual(f2, f1); // PASSES
This is String#Equals
public override bool Equals(object obj)
{
string strB = obj as string;
if ((strB == null) && (this != null))
{
return false;
}
return EqualsHelper(this, strB);
}
Supplying an argument other than a String to String#Equals is going to return false. I'd suggest a 'rethink' to get around this.
I suggest using object.ReferenceEquals() if you are internally trying to validate whether x or y is null.
public static bool operator ==(field x, Object y)
{
if (object.ReferenceEquals(x, null) && object.ReferenceEquals(y, null))
{
return true;
}
else if (object.ReferenceEquals(x, null) || object.ReferenceEquals(y, null))
{
return false;
}
else
{
return (x.m_field == y.ToString());
}
}