Convert Nulls to Empty String in an object - c#

What is the easiest way to take an objects and convert any of its values from null to string.empty ?
I was thinking about a routine that I can pass in any object, but I am not sure how to loop through all the values.

When your object exposes it's values via properties you can write something like:
string Value { get { return m_Value ?? string.Empty; } }
Another solution is to use reflection. This code will check properties of type string:
var myObject = new MyObject();
foreach( var propertyInfo in myObject.GetType().GetProperties() )
{
if(propertyInfo.PropertyType == typeof(string))
{
if( propertyInfo.GetValue( myObject, null ) == null )
{
propertyInfo.SetValue( myObject, string.Empty, null );
}
}
}

Using reflection, you could something similar to :
public static class Extensions
{
public static void Awesome<T>(this T myObject) where T : class
{
PropertyInfo[] properties = typeof(T).GetProperties();
foreach(var info in properties)
{
// if a string and null, set to String.Empty
if(info.PropertyType == typeof(string) &&
info.GetValue(myObject, null) == null)
{
info.SetValue(myObject, String.Empty, null);
}
}
}
}

Presumably, you have a report or a form somewhere showing "null" all over the place, instead of a nice, pleasant "".
It's best to leave the nulls as they are, and modify your display code wherever appropriate. Thus, a line like this:
label1.Text = someObject.ToString();
should become:
if (someObject == null)
{
label1.Text = ""; // or String.Empty, if you're one of *those* people
}
else
{
label1.Text = someObject.ToString();
}
and you can functionalize it as necessary:
public void DisplayObject(Label label, Object someObject)
{
if (someObject == null)
{
label.Text = ""; // or String.Empty, if you're one of *those* people
}
else
{
label.Text = someObject.ToString();
}
}

You could use reflection. Here's an example with one level of nesting:
class Foo
{
public string Prop1 { get; set; }
public string Prop2 { get; set; }
public string Prop3 { get; set; }
}
class Program
{
static void Main(string[] args)
{
var foo = new Foo
{
Prop1 = (string)null,
Prop2 = (string)null,
Prop3 = (string)null,
};
var props = typeof(Foo).GetProperties()
.Where(x => x.PropertyType == typeof(string));
foreach (var p in props)
{
p.SetValue(foo, string.Empty, null);
}
}
}

You can do that via reflection without too much trouble, and I am sure that by the time I post this there will be answers that tell you exactly how to do that.
But I personally don't like the reflection option.
I prefer to maintain object invariants for all of the object's members through a variety of means. For string members, the invariant is often that it not be null, and sometimes there are maximum length requirements as well (for storage in a database, for example). Other members have other sorts of invariants.
The first step is to create a method that checks all the invariants that you define for the object.
[Conditional("DEBUG")]
private void CheckObjectInvariant()
{
Debug.Assert(name != null);
Debug.Assert(name.Length <= nameMaxLength);
...
}
Then you call this after any method that manipulates the object in any way. Since it is decorated with the ConditionalAttribute, none of these calls will appear in the release version of the application.
Then you just have to make sure that none of the code allows any violations of these invariants. This means that the string fields need to have either initializers in their declarations or they need to be set in all the constructors for the object.
A special problem, and the one that probably motivated this question, is what to do about automatic properties.
public string Name { get; set; }
Obviously, this can be set to null at any time, and there's nothing you can do about that.
There are two options with regard to automatic properties. First, you can just not use them at all. This avoids the problem entirely. Second, you can just allow any possible string value. That is, any code that uses that property has to expect nulls, 10 mb strings or anything in between.
Even if you go with the reflection option to remove nulls, you still have to know when to call the magic-null-removal method on the object to avoid NullReferenceExceptions, so you haven't really bought anything that way.

+1 to Tanascius's answer. I used this answer but tweaked it a bit.
First I only grab the properties that are strings, so it doesn't loop through all my properties. Secondly, I placed in it my BaseEntity class that all my entities inherit from, which makes it global, so I don't have to put it on all my Entities.
public class BaseEntity
{
public int Id { get; set; }
public BaseEntity()
{
var stringProperties = this.GetType().GetProperties().Where(x => x.PropertyType == typeof(string));
foreach (var property in stringProperties)
{
if (property.GetValue(this, null) == null)
{
property.SetValue(this, string.Empty, null);
}
}
}
}

Related

Convert class object to class index

Class Person {
int Id
string Name
string Address
// etc
}
instead of accessing it like Person.Id, Person.Name, Person.Address. I want to access it via index just like Person['Id'], Person['Name']. Is there any codegen or linq conversion for this.
You can use Json.NET's JObject class
Person p = new Person() { Id = 1, Address = "A", Name = "B" };
var obj = JObject.FromObject(p);
Console.WriteLine(obj["Id"]); //1
This is a pure C# implementation:
class Program
{
static void Main(string[] args)
{
Person person = new Person
{
Id = 1,
Name = "test",
Address = "tost"
};
Console.WriteLine(person["Id"]);
person["Id"] = 5;
Console.WriteLine(person["Id"]);
}
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public object this[string propertyName]
{
get
{
return this.GetType().GetProperty(propertyName).GetValue(this);
}
set
{
this.GetType().GetProperty(propertyName).SetValue(this, value);
}
}
}
Output:
1
5
Important note:
I would never recommend to use this in a production environment, if you want to use an handly implemented system, atleast you should handle types and properties extractions to avoid consuming more memory than needed and exceeding overheads.
Using reflection and indexers:
public class ExampleClass{
public object this[string name]
{
get
{
var properties = typeof(ExampleClass)
.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var property in properties)
{
if (property.Name == name && property.CanRead)
return property.GetValue(this, null);
}
throw new ArgumentException("Can't find property");
}
set {
return;
}
}
}
An indexer won't make data comparison any easier. I suspect the real question is how to handle data in C# the same way Python's DataFrames work. ADO.NET provides the DataTable class since .NET 1.0. It's meant more for database processing than data analysis, altough it does support operations like searching, merging and diffing.
For data anlysis, the new Microsoft.Data.Analysis package provides the DataFrame class.
That said, to read properties by name, you'll have to use Reflection, an expensive operation. One way to make this cheaper is to cache type and property descriptors. Instead of writing the code yourself though, you can use Marc Gravel's FastMember library that does just that. With this, you can create a TypeAccessor or ObjectAccessor type and read properties by name, eg :
var wrapped = ObjectAccessor.Create(obj);
string propName = // something known only at runtime
Console.WriteLine(wrapped[propName]);
If you want to read from multiple objects, you'll need a TypeAccessor :
var accessor = TypeAccessor.Create(type);
string propName = // something known only at runtime
while( /* some loop of data */ )
{
accessor[obj, propName] = rowValue;
}
The library isn't that big. If you aren't allowed to use NuGet packages, you could copy the code into your project.

Checking if Object has null in every property

I have class with multiple properties;
public class Employee
{
public string TYPE { get; set; }
public int? SOURCE_ID { get; set; }
public string FIRST_NAME { get; set; }
public string LAST_NAME { get; set; }
public List<Department> departmentList { get; set; }
public List<Address> addressList { get; set; }
}
sometimes this object return me with value in any property say
Employee emp = new Employee();
emp.FIRST_NAME= 'abc';
remaining values are null. This is OK
But, How do I check when all values in properties of objects are null
like string.IsNullOrEmpty() for object ?
curretly I am checking like this;
if(emp.FIRST_NAME == null && emp.LAST_NAME == null && emp.TYPE == null && emp.departmentList == null ...)
EDIT
This answer has received some votes in the last time, so I decided to improve it a little, adding simple caching so that ArePropertiesNotNull does not retrieve the properties every time it is called, but rather only once for every type.
public static class PropertyCache<T>
{
private static readonly Lazy<IReadOnlyCollection<PropertyInfo>> publicPropertiesLazy
= new Lazy<IReadOnlyCollection<PropertyInfo>>(() => typeof(T).GetProperties());
public static IReadOnlyCollection<PropertyInfo> PublicProperties => PropertyCache<T>.publicPropertiesLazy.Value;
}
public static class Extensions
{
public static bool ArePropertiesNotNull<T>(this T obj)
{
return PropertyCache<T>.PublicProperties.All(propertyInfo => propertyInfo.GetValue(obj) != null);
}
}
(Old answer below.)
You could use reflection as proposed by Joel Harkes, e.g. I put together this reusable, ready-to-use extension method
public static bool ArePropertiesNotNull<T>(this T obj)
{
return typeof(T).GetProperties().All(propertyInfo => propertyInfo.GetValue(obj) != null);
}
which can then be called like this
var employee = new Employee();
bool areAllPropertiesNotNull = employee.ArePropertiesNotNull();
And now you can check the areAllPropertiesNotNull flag which indicates whether all properties are not null. Returns true if all properties are not null, otherwise false.
Advantages of this approach
It doesn't matter whether or not the property type is nullable or not for the check.
Since above method is generic, you can use it for any type you want and don't have to write boilerplate code for every type you want to check.
It is more future-proof in case you change the class later. (noted by ispiro).
Disadvantages
Reflection can be quite slow, and in this case it is certainly slower than writing explicit code as you currently do. Using simple caching (as proposed by Reginald Blue will remove much of that overhead.
In my opinion, the slight performance overhead can be neglected since development time and repetition of code are reduced when using the ArePropertiesNotNull, but YMMV.
Either you do this by writing down the code to check every property manually (best option) or you use reflection (read more here)
Employee emp = new Employee();
var props = emp.GetType().GetProperties())
foreach(var prop in props)
{
if(prop.GetValue(foo, null) != null) return false;
}
return true;
example from here
Note that int cannot be null! and its default value will be 0. thus its better to check prop == default(int) than == null
option 3
Another option is to implement INotifyPropertyChanged.
On a change set a boolean field value isDirty to true and than you only need to check if this value is true to know if any property has been set (even if property was set with null.
Warning: this method every property can still be null but only checks if a setter was called (changing a value).

Instantiate an instance of a Type including all object properties and adhere to inheritance

I'm not sure if that title is reflective of the actual question, so let me explain. Is there a way to instantiate a class and recursively instantiate all properties that are classes?
For example :
public class Base
{
public int BaseValue{ get; set;}
}
public class Extended : Base
{
public int ExtendedValue{ get; set;}
public AnotherExtendedClass AnotherClass { get; set;}
}
I would like to create a json payload comprised of an empty instance of Extended with all default values and properties instantiated. And use it like:
string representation = Test.CreateDefaultEmptyJson(Extended);
public static string CreateDefaultEmptyJson(Type type)
{
JsonSerializerSettings settings = new JsonSerializerSettings().Configure();
var defaultInstance= Activator.CreateInstance(type);
return JsonConvert.SerializeObject(defaultInstance, settings);
}
The output does not include the Extended class properties. I get back :
{
"BaseValue":0
}
When I would really like to see ( or something similar ):
{
"BaseValue":0,
{
"ExtendedValue":0,
{
...
}
}
}
I suppose I could recursively iterate all types of Extended and call the default constructor, however, before I go down that road there may be a few lines of code to accomplish the same.
As far as I know there is not a built-in way to do this short of writing your own recursive method.
However, assuming that:
your classes all have parameterless (default) constructors,
the non-primitive properties are all concrete types (not interfaces), and
you don't have any reference loops in your class structure,
then you can create such a method in about a dozen lines of code:
public static string CreateDefaultEmptyJson(Type type)
{
return JsonConvert.SerializeObject(RecursiveCreateInstance(type), Formatting.Indented);
}
public static object RecursiveCreateInstance(Type type)
{
object obj = null;
ConstructorInfo ctor = type.GetConstructor(Type.EmptyTypes);
if (ctor != null)
{
obj = ctor.Invoke(null);
foreach (PropertyInfo prop in type.GetProperties())
{
Type propType = prop.PropertyType;
if (prop.CanWrite && propType.IsClass)
{
prop.SetValue(obj, RecursiveCreateInstance(propType));
}
}
}
return obj;
}
Fiddle: https://dotnetfiddle.net/3VMTsC
If the above assumptions don't hold, then things get complicated fast. If you're running into issues where you need an easy way to create fake objects for testing purposes, then you might want to look into using a mocking framework.
This hastily-written class begins to address your question. It returns the settable properties which return reference types and walks through them recursively, creating instances as needed.
It doesn't cover
Indexed properties
Depth of recursion
You may be better off just setting defaults on the properties themselves so that the class won't be created with undesirable nulls.
public class PropertyPopulator
{
public void PopulateProperties(object target)
{
var properties = target.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(p => p.PropertyType.IsClass && p.CanWrite && p.CanRead);
foreach (var property in properties)
{
var propertyValue = property.GetValue(target);
if (propertyValue == null)
{
var constructor = property.PropertyType.GetConstructor(new Type[] { });
if (constructor != null)
{
propertyValue = constructor.Invoke(new object[] { });
property.SetValue(target, propertyValue);
PopulateProperties(propertyValue);
}
}
}
}
}

C# : LINQ query to list all empty properties of a class

I have a class like this :
public class Test
{
public string STR1{ get; set; }
public INT INT1{ get; set; }
public DOUBLE DBL1{ get; set; }
public DATETIME DT1{ get; set; }
}
Normally, before saving the object, i will have to check all the properties inside this Class, and return a warning message if there is any empty/null property. There is easy way to do this by simply check each property like this :
if (string.IsNullOrEmpty(t.STR1))
return "STR1 is empty"
if (t.INT1 == 0)
return "INT1 = 0";
if (t.DBL1 == 0)
return "DBL1 = 0";
if (t.DT1 == DateTime.MinValue)
return "DT1 is empty"
But what if my class has more properties, actually it contains about 42 properties now, and still growing up. So i was thinking for a "cleaner" way to perform this check, and i found this topic which is quiet similar to my issue : Reflection (?) - Check for null or empty for each property/field in a class?
But this solution does not meet my need as i have to list the values that = null/empty string/0/DateTime.MinValue
Believe me, i wanted to post my "tried code" but i can't figure out a sensible LINQ query for this task (i'm a novice in C#)
Any help is greatly appreciated !
Since you need to test objects of different types, you can combine the solution from the linked question with use of dynamic to dispatch to the proper method.
First, define an overloaded method for each type.
private static IsEmpty(string s) { return string.IsNullOrEmpty(s); }
private static IsEmpty(double f) { return f == 0.0; }
private static IsEmpty(int i) { return i == 0; }
private static IsEmpty(DateTime d) { return d == DateTime.MinValue; }
Now you can use these methods in your check:
List<string> emptyProperties = typeof(MyType).GetProperties()
.Select(prop => new { Prop = prop, Val = prop.GetValue(obj, null) } )
.Where(val => IsEmpty((dynamic)val.Val) // <<== The "magic" is here
.Select(val => val.Prop.Name)
.ToList();
The tricky part of the code casts the value to dynamic, and then tells the runtime to find the most appropriate IsEmpty method for it. The downside to this approach is that the compiler has no way of telling whether the method is going to be found or not, so you may get exceptions at runtime for properties of unexpected type.
You can prevent these failures by adding a catch-all method taking object, like this:
private static IsEmpty(object o) { return o == null; }

Cleaner way to do a null check in C#? [duplicate]

This question already has answers here:
C# elegant way to check if a property's property is null
(20 answers)
Closed 9 years ago.
Suppose, I have this interface,
interface IContact
{
IAddress address { get; set; }
}
interface IAddress
{
string city { get; set; }
}
class Person : IPerson
{
public IContact contact { get; set; }
}
class test
{
private test()
{
var person = new Person();
if (person.contact.address.city != null)
{
//this will never work if contact is itself null?
}
}
}
Person.Contact.Address.City != null (This works to check if City is null or not.)
However, this check fails if Address or Contact or Person itself is null.
Currently, one solution I could think of was this:
if (Person != null && Person.Contact!=null && Person.Contact.Address!= null && Person.Contact.Address.City != null)
{
// Do some stuff here..
}
Is there a cleaner way of doing this?
I really don't like the null check being done as (something == null). Instead, is there another nice way to do something like the something.IsNull() method?
In a generic way, you may use an expression tree and check with an extension method:
if (!person.IsNull(p => p.contact.address.city))
{
//Nothing is null
}
Full code:
public class IsNullVisitor : ExpressionVisitor
{
public bool IsNull { get; private set; }
public object CurrentObject { get; set; }
protected override Expression VisitMember(MemberExpression node)
{
base.VisitMember(node);
if (CheckNull())
{
return node;
}
var member = (PropertyInfo)node.Member;
CurrentObject = member.GetValue(CurrentObject,null);
CheckNull();
return node;
}
private bool CheckNull()
{
if (CurrentObject == null)
{
IsNull = true;
}
return IsNull;
}
}
public static class Helper
{
public static bool IsNull<T>(this T root,Expression<Func<T, object>> getter)
{
var visitor = new IsNullVisitor();
visitor.CurrentObject = root;
visitor.Visit(getter);
return visitor.IsNull;
}
}
class Program
{
static void Main(string[] args)
{
Person nullPerson = null;
var isNull_0 = nullPerson.IsNull(p => p.contact.address.city);
var isNull_1 = new Person().IsNull(p => p.contact.address.city);
var isNull_2 = new Person { contact = new Contact() }.IsNull(p => p.contact.address.city);
var isNull_3 = new Person { contact = new Contact { address = new Address() } }.IsNull(p => p.contact.address.city);
var notnull = new Person { contact = new Contact { address = new Address { city = "LONDON" } } }.IsNull(p => p.contact.address.city);
}
}
Your code may have bigger problems than needing to check for null references. As it stands, you are probably violating the Law of Demeter.
The Law of Demeter is one of those heuristics, like Don't Repeat Yourself, that helps you write easily maintainable code. It tells programmers not to access anything too far away from the immediate scope. For example, suppose I have this code:
public interface BusinessData {
public decimal Money { get; set; }
}
public class BusinessCalculator : ICalculator {
public BusinessData CalculateMoney() {
// snip
}
}
public BusinessController : IController {
public void DoAnAction() {
var businessDA = new BusinessCalculator().CalculateMoney();
Console.WriteLine(businessDA.Money * 100d);
}
}
The DoAnAction method violates the Law of Demeter. In one function, it accesses a BusinessCalcualtor, a BusinessData, and a decimal. This means that if any of the following changes are made, the line will have to be refactored:
The return type of BusinessCalculator.CalculateMoney() changes.
The type of BusinessData.Money changes
Considering the situation at had, these changes are rather likely to happen. If code like this is written throughout the codebase, making these changes could become very expensive. Besides that, it means that your BusinessController is coupled to both the BusinessCalculator and the BusinessData types.
One way to avoid this situation is rewritting the code like this:
public class BusinessCalculator : ICalculator {
private BusinessData CalculateMoney() {
// snip
}
public decimal CalculateCents() {
return CalculateMoney().Money * 100d;
}
}
public BusinessController : IController {
public void DoAnAction() {
Console.WriteLine(new BusinessCalculator().CalculateCents());
}
}
Now, if you make either of the above changes, you only have to refactor one more piece of code, the BusinessCalculator.CalculateCents() method. You've also eliminated BusinessController's dependency on BusinessData.
Your code suffers from a similar issue:
interface IContact
{
IAddress address { get; set; }
}
interface IAddress
{
string city { get; set; }
}
class Person : IPerson
{
public IContact contact { get; set; }
}
class Test {
public void Main() {
var contact = new Person().contact;
var address = contact.address;
var city = address.city;
Console.WriteLine(city);
}
}
If any of the following changes are made, you will need to refactor the main method I wrote or the null check you wrote:
The type of IPerson.contact changes
The type of IContact.address changes
The type of IAddress.city changes
I think you should consider a deeper refactoring of your code than simply rewriting a null check.
That said, I think that there are times where following the Law of Demeter is inappropriate. (It is, after all, a heuristic, not a hard-and-fast rule, even though it's called a "law.")
In particular, I think that if:
You have some classes that represent records stored in the persistence layer of your program, AND
You are extremely confident that you will not need to refactor those classes in the future,
ignoring the Law of Demeter is acceptable when dealing specifically with those classes. This is because they represent the data your application works with, so reaching from one data object into another is a way of exploring the information in your program. In my example above, the coupling caused by violating the Law of Demeter was much more severe: I was reaching all the way from a controller near the top of my stack through a business logic calculator in the middle of the stack into a data class likely in the persistence layer.
I bring this potential exception to the Law of Demeter up because with names like Person, Contact, and Address, your classes look like they might be data-layer POCOs. If that's the case, and you are extremely confident that you will never need to refactor them in the future, you might be able to get away with ignoring the Law of Demeter in your specific situation.
in your case you could create a property for person
public bool HasCity
{
get
{
return (this.Contact!=null && this.Contact.Address!= null && this.Contact.Address.City != null);
}
}
but you still have to check if person is null
if (person != null && person.HasCity)
{
}
to your other question, for strings you can also check if null or empty this way:
string s = string.Empty;
if (!string.IsNullOrEmpty(s))
{
// string is not null and not empty
}
if (!string.IsNullOrWhiteSpace(s))
{
// string is not null, not empty and not contains only white spaces
}
A totally different option (which I think is underused) is the null object pattern. It's hard to tell whether it makes sense in your particular situation, but it might be worth a try. In short, you will have a NullContact implementation, a NullAddress implementation and so on that you use instead of null. That way, you can get rid of most of the null checks, of course at the expense at some thought you have to put into the design of these implementations.
As Adam pointed out in his comment, this allows you to write
if (person.Contact.Address.City is NullCity)
in cases where it is really necessary. Of course, this only makes sense if city really is a non-trivial object...
Alternatively, the null object can be implemented as a singleton (e.g., look here for some practical instructions concerning the usage of the null object pattern and here for instructions concerning singletons in C#) which allows you to use classical comparison.
if (person.Contact.Address.City == NullCity.Instance)
Personally, I prefer this approach because I think it is easier to read for people not familiar with the pattern.
Update 28/04/2014: Null propagation is planned for C# vNext
There are bigger problems than propagating null checks. Aim for readable code that can be understood by another developer, and although it's wordy - your example is fine.
If it is a check that is done frequently, consider encapsulating it inside the Person class as a property or method call.
That said, gratuitous Func and generics!
I would never do this, but here is another alternative:
class NullHelper
{
public static bool ChainNotNull<TFirst, TSecond, TThird, TFourth>(TFirst item1, Func<TFirst, TSecond> getItem2, Func<TSecond, TThird> getItem3, Func<TThird, TFourth> getItem4)
{
if (item1 == null)
return false;
var item2 = getItem2(item1);
if (item2 == null)
return false;
var item3 = getItem3(item2);
if (item3 == null)
return false;
var item4 = getItem4(item3);
if (item4 == null)
return false;
return true;
}
}
Called:
static void Main(string[] args)
{
Person person = new Person { Address = new Address { PostCode = new Postcode { Value = "" } } };
if (NullHelper.ChainNotNull(person, p => p.Address, a => a.PostCode, p => p.Value))
{
Console.WriteLine("Not null");
}
else
{
Console.WriteLine("null");
}
Console.ReadLine();
}
The second question,
I really don't like the null check being done as (something == null). Instead, is there another nice way to do something like the something.IsNull() method?
could be solved using an extension method:
public static class Extensions
{
public static bool IsNull<T>(this T source) where T : class
{
return source == null;
}
}
If for some reason you don't mind going with one of the more 'over the top' solutions, you might want to check out the solution described in my blog post. It uses the expression tree to find out whether the value is null before evaluating the expression. But to keep performance acceptable, it creates and caches IL code.
The solution allows you do write this:
string city = person.NullSafeGet(n => n.Contact.Address.City);
You can write:
public static class Extensions
{
public static bool IsNull(this object obj)
{
return obj == null;
}
}
and then:
string s = null;
if(s.IsNull())
{
}
Sometimes this makes sense. But personally I would avoid such things... because this is is not clear why you can call a method of the object that is actually null.
Do it in a separate method like:
private test()
{
var person = new Person();
if (!IsNull(person))
{
// Proceed
........
Where your IsNull method is
public bool IsNull(Person person)
{
if(Person != null &&
Person.Contact != null &&
Person.Contact.Address != null &&
Person.Contact.Address.City != null)
return false;
return true;
}
Do you need C#, or do you only want .NET? If you can mix another .NET language, have a look at Oxygene. It's an amazing, very modern OO language that targets .NET (and also Java and Cocoa as well. Yep. All natively, it really is quite an amazing toolchain.)
Oxygene has a colon operator which does exactly what you ask. To quote from their miscellaneous language features page:
The Colon (":") Operator
In Oxygene, like in many of the languages it
was influenced by, the "." operator is used to call members on a class
or object, such as
var x := y.SomeProperty;
This "dereferences" the object contained in
"y", calls (in this case) the property getter and returns its value.
If "y" happens to be unassigned (i.e. "nil"), an exception is thrown.
The ":" operator works in much the same way, but instead of throwing
an exception on an unassigned object, the result will simply be nil.
For developers coming from Objective-C, this will be familiar, as that
is how Objective-C method calls using the [] syntax work, too.
... (snip)
Where ":" really shines is when accessing properties in a chain, where
any element might be nil. For example, the following code:
var y := MyForm:OkButton:Caption:Length;
will run without error, and
return nil if any of the objects in the chain are nil — the form, the
button or its caption.
try
{
// do some stuff here
}
catch (NullReferenceException e)
{
}
Don't actually do this. Do the null checks, and figure out what formatting you can best live with.
I have an extension that could be useful for this; ValueOrDefault(). It accepts a lambda statement and evaluates it, returning either the evaluated value or a default value if any expected exceptions (NRE or IOE) are thrown.
/// <summary>
/// Provides a null-safe member accessor that will return either the result of the lambda or the specified default value.
/// </summary>
/// <typeparam name="TIn">The type of the in.</typeparam>
/// <typeparam name="TOut">The type of the out.</typeparam>
/// <param name="input">The input.</param>
/// <param name="projection">A lambda specifying the value to produce.</param>
/// <param name="defaultValue">The default value to use if the projection or any parent is null.</param>
/// <returns>the result of the lambda, or the specified default value if any reference in the lambda is null.</returns>
public static TOut ValueOrDefault<TIn, TOut>(this TIn input, Func<TIn, TOut> projection, TOut defaultValue)
{
try
{
var result = projection(input);
if (result == null) result = defaultValue;
return result;
}
catch (NullReferenceException) //most reference types throw this on a null instance
{
return defaultValue;
}
catch (InvalidOperationException) //Nullable<T> throws this when accessing Value
{
return defaultValue;
}
}
/// <summary>
/// Provides a null-safe member accessor that will return either the result of the lambda or the default value for the type.
/// </summary>
/// <typeparam name="TIn">The type of the in.</typeparam>
/// <typeparam name="TOut">The type of the out.</typeparam>
/// <param name="input">The input.</param>
/// <param name="projection">A lambda specifying the value to produce.</param>
/// <returns>the result of the lambda, or default(TOut) if any reference in the lambda is null.</returns>
public static TOut ValueOrDefault<TIn, TOut>(this TIn input, Func<TIn, TOut> projection)
{
return input.ValueOrDefault(projection, default(TOut));
}
The overload not taking a specific default value will return null for any reference type. This should work in your scenario:
class test
{
private test()
{
var person = new Person();
if (person.ValueOrDefault(p=>p.contact.address.city) != null)
{
//the above will return null without exception if any member in the chain is null
}
}
}
Such a reference chain may occurre for example if you use an ORM tool, and want to keep your classes as pure as possible. In this scenario I think it cannot be avoided nicely.
I have the following extension method "family", which checks if the object on which it's called is null, and if not, returns one of it's requested properties, or executes some methods with it. This works of course only for reference types, that's why I have the corresponding generic constraint.
public static TRet NullOr<T, TRet>(this T obj, Func<T, TRet> getter) where T : class
{
return obj != null ? getter(obj) : default(TRet);
}
public static void NullOrDo<T>(this T obj, Action<T> action) where T : class
{
if (obj != null)
action(obj);
}
These methods add almost no overhead compared to the manual solution (no reflection, no expression trees), and you can achieve a nicer syntax with them (IMO).
var city = person.NullOr(e => e.Contact).NullOr(e => e.Address).NullOr(e => e.City);
if (city != null)
// do something...
Or with methods:
person.NullOrDo(p => p.GoToWork());
However, one could definetely argue about the length of code didn't change too much.
In my opinion, the equality operator is not a safer and better way for reference equality.
It's always better to use ReferenceEquals(obj, null). This will always work. On the other hand, the equality operator (==) could be overloaded and might be checking if the values are equal instead of the references, so I will say ReferenceEquals() is a safer and better way.
class MyClass {
static void Main() {
object o = null;
object p = null;
object q = new Object();
Console.WriteLine(Object.ReferenceEquals(o, p));
p = q;
Console.WriteLine(Object.ReferenceEquals(p, q));
Console.WriteLine(Object.ReferenceEquals(o, p));
}
}
Reference: MSDN article Object.ReferenceEquals Method.
But also here are my thoughts for null values
Generally, returning null values is the best idea if anyone is trying to indicate that there is no data.
If the object is not null, but empty, it implies that data has been returned, whereas returning null clearly indicates that nothing has been returned.
Also IMO, if you will return null, it will result in a null exception if you attempt to access members in the object, which can be useful for highlighting buggy code.
In C#, there are two different kinds of equality:
reference equality and
value equality.
When a type is immutable, overloading operator == to compare value equality instead of reference equality can be useful.
Overriding operator == in non-immutable types is not recommended.
Refer to the MSDN article Guidelines for Overloading Equals() and Operator == (C# Programming Guide) for more details.
As much as I love C#, this is one thing that's kind of likable about C++ when working directly with object instances; some declarations simply cannot be null, so there's no need to check for null.
The best way you can get a slice of this pie in C# (which might be a bit too much redesigning on your part - in which case, take your pick of the other answers) is with struct's. While you could find yourself in a situation where a struct has uninstantiated "default" values (ie, 0, 0.0, null string) there's never a need to check "if (myStruct == null)".
I wouldn't switch over to them without understanding their use, of course. They tend to be used for value types, and not really for large blocks of data - anytime you assign a struct from one variable to another, you tend to be actually copying the data across, essentially creating a copy of each of the original's values (you can avoid this with the ref keyword - again, read up on it rather than just using it). Still, it may fit for things like StreetAddress - I certainly wouldn't lazily use it on anything I didn't want to null-check.
Depending on what the purpose of using the "city" variable is, a cleaner way could be to separate the null checks into different classes. That way you also wouldn't be violating the Law of Demeter. So instead of:
if (person != null && person.contact != null && person.contact.address != null && person.contact.address.city != null)
{
// do some stuff here..
}
You'd have:
class test
{
private test()
{
var person = new Person();
if (person != null)
{
person.doSomething();
}
}
}
...
/* Person class */
doSomething()
{
if (contact != null)
{
contact.doSomething();
}
}
...
/* Contact class */
doSomething()
{
if (address != null)
{
address.doSomething();
}
}
...
/* Address class */
doSomething()
{
if (city != null)
{
// do something with city
}
}
Again, it depends on the purpose of the program.
In what circumstances can those things be null? If nulls would indicate a bug in the code then you could use code contracts. They will pick it up if you get nulls during testing, then will go away in the production version. Something like this:
using System.Diagnostics.Contracts;
[ContractClass(typeof(IContactContract))]
interface IContact
{
IAddress address { get; set; }
}
[ContractClassFor(typeof(IContact))]
internal abstract class IContactContract: IContact
{
IAddress address
{
get
{
Contract.Ensures(Contract.Result<IAddress>() != null);
return default(IAddress); // dummy return
}
}
}
[ContractClass(typeof(IAddressContract))]
interface IAddress
{
string city { get; set; }
}
[ContractClassFor(typeof(IAddress))]
internal abstract class IAddressContract: IAddress
{
string city
{
get
{
Contract.Ensures(Contract.Result<string>() != null);
return default(string); // dummy return
}
}
}
class Person
{
[ContractInvariantMethod]
protected void ObjectInvariant()
{
Contract.Invariant(contact != null);
}
public IContact contact { get; set; }
}
class test
{
private test()
{
var person = new Person();
Contract.Assert(person != null);
if (person.contact.address.city != null)
{
// If you get here, person cannot be null, person.contact cannot be null
// person.contact.address cannot be null and person.contact.address.city cannot be null.
}
}
}
Of course, if the possible nulls are coming from somewhere else then you'll need to have already conditioned the data. And if any of the nulls are valid then you shouldn't make non-null a part of the contract, you need to test for them and handle them appropriately.
One way to remove null checks in methods is to encapsulate their functionality elsewhere. One way to do this is through getters and setters. For instance, instead of doing this:
class Person : IPerson
{
public IContact contact { get; set; }
}
Do this:
class Person : IPerson
{
public IContact contact
{
get
{
// This initializes the property if it is null.
// That way, anytime you access the property "contact" in your code,
// it will check to see if it is null and initialize if needed.
if(_contact == null)
{
_contact = new Contact();
}
return _contact;
}
set
{
_contact = value;
}
}
private IContact _contact;
}
Then, whenever you call "person.contact", the code in the "get" method will run, thus initializing the value if it is null.
You could apply this exact same methodology to all of the properties that could be null across all of your types. The benefits to this approach are that it 1) prevents you from having to do null checks in-line and it 2) makes your code more readable and less prone to copy-paste errors.
It should be noted, however, that if you find yourself in a situation where you need to perform some action if one of the properties is null (i.e. does a Person with a null Contact actually mean something in your domain?), then this approach will be a hindrance rather than a help. However, if the properties in question should never be null, then this approach will give you a very clean way of representing that fact.
--jtlovetteiii
You could use reflection, to avoid forcing implementation of interfaces and extra code in every class. Simply a Helper class with static method(s). This might not be the most efficient way, be gentle with me, I'm a virgin (read, noob)..
public class Helper
{
public static bool IsNull(object o, params string[] prop)
{
if (o == null)
return true;
var v = o;
foreach (string s in prop)
{
PropertyInfo pi = v.GetType().GetProperty(s); //Set flags if not only public props
v = (pi != null)? pi.GetValue(v, null) : null;
if (v == null)
return true;
}
return false;
}
}
//In use
isNull = Helper.IsNull(p, "ContactPerson", "TheCity");
Offcourse if you have a typo in the propnames, the result will be wrong (most likely)..

Categories

Resources