I have a class with the following code. This looks OK but isn’t…
public class Lot : INotifyPropertyChanged { private string _actualHighestBidder; public string ActualHighestBidder { get { return _actualHighestBidder; } set { if (_actualHighestBidder.Equals(value) != true) { _actualHighestBidder = value; RaisePropertyChanged("ActualHighestBidder"); } } } -- SNIP -- Implementation of INotifyPropertyChanged omitted
Spot the problem in the code above!!!
Scroll down
…
Scroll down
…
The private variable “_actualHighestBidder” is a string and is null.
Calling Equals on a null variable causes an annoying NullReferenceException.
There are 2 ways to solve this
1. Initialize your private backed field
private string _actualHighestBidder = string.Empty;
2. Test for null
public string ActualHighestBidder { get { return _actualHighestBidder; } set { if ((_actualHighestBidder == null || _actualHighestBidder.Equals(value) != true)) { _actualHighestBidder = value; RaisePropertyChanged("ActualHighestBidder"); } } }
I prefer the first method
but
how do we make sure we are not introducing this bugs in the future?
Note
This bug is very annoying, because we get this exception at runtime!
Idea!
Set all properties to some values with reflection
So that we can have a test like this
[TestMethod()] public void LotProperties_SetAllProperties_NoException() { Lot target = new Lot(); target.SetAllPublicProperties(); target.GetAllPublicProperties(); Assert.IsNotNull(target); }
My implementation of these 2 methods look like the below…
The method SetAllPublicProperties, sets all properties via Reflection
And the method GetAllPublicProperties does the same but tries to read the values!!
using System; using System.Diagnostics; using System.Reflection; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Tests.Integration.Utils { public static class ReflectionHelper { public static void SetAllPublicProperties(this object target) { Type targetType = target.GetType(); foreach (MemberInfo memberInfo in targetType.GetProperties()) { //Debug.WriteLine("memberInfo: " + memberInfo.ToString()); PropertyInfo propertyInfo = memberInfo as PropertyInfo; if (propertyInfo != null) { //Debug.WriteLine("propertyInfo: field " + propertyInfo.ToString()); if (propertyInfo.CanWrite) { MethodInfo setMethod = propertyInfo.GetSetMethod(); if (propertyInfo.PropertyType == typeof(string)) { setMethod.Invoke(target, new object[] { "String parameter" }); } else if (propertyInfo.PropertyType == typeof(bool)) { setMethod.Invoke(target, new object[] { true }); } else if (propertyInfo.PropertyType == typeof(Single)) { setMethod.Invoke(target, new object[] { 123 }); } else if (propertyInfo.PropertyType == typeof(Single?)) { setMethod.Invoke(target, new object[] { null }); setMethod.Invoke(target, new object[] { (Single?)123 }); } else { Assert.Fail("Generic Poperty setter not implemented for type: " + propertyInfo.PropertyType); } } } } } public static void GetAllPublicProperties(this object target) { Type targetType = target.GetType(); foreach (MemberInfo memberInfo in targetType.GetProperties()) //System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags. { //Debug.WriteLine("memberInfo: " + memberInfo.ToString()); PropertyInfo propertyInfo = memberInfo as PropertyInfo; if (propertyInfo != null) { //Debug.WriteLine("propertyInfo: field " + propertyInfo.ToString()); if (propertyInfo.CanRead) { MethodInfo getMethod = propertyInfo.GetGetMethod(); object readValue = getMethod.Invoke(target, null); Debug.WriteLine("Value from property: " + readValue); } } } } } }
Use it and extend it to all your needed types!
4 comments:
.net is one of the most user friendly software development platforms. ASP.net development gives the way to develop complex web applications and web pages. Even most of the Business Intelligence software are being made on .net platforms with integrating ASP.net as an essential functional part.
very useful but alot of types missing!
Same idea that CrashTest.Net is using.
http://www.crashtestnet.de/
3. String.IsNullOrEmpty( _actualHighestBidder )
Post a Comment