I am trying to improve performance in the code below and kinda know how but not sure which is the best approach.
The first hit will take longer but subsequent hits should be quicker. Now, I could cache T (where T is a class) and then check the cache to see if "T" exists, if so - go ahead and get its related information (NamedArguments) and go through each of the NamedArguments and finally if the criteria matches, go ahead and set the value of the current property.
I just want to make it more efficient and performant. Any ideas?
var myProps = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static).Where(prop => Attribute.IsDefined(prop, typeof(MyCustomAttribute)) && prop.CanWrite && prop.GetSetMethod() != null);
foreach (var currentProperty in myProps)
{
foreach (var currentAttributeForProperty in currentProperty.GetCustomAttributesData())
{
foreach (var currentNamedArgument in currentAttributeForProperty.NamedArguments)
{
if (string.Equals(currentNamedArgument.MemberInfo.Name, "PropName", StringComparison.OrdinalIgnoreCase))
{
currentAttribParamValue = currentNamedArgument.TypedValue.Value == null ? null : currentNamedArgument.TypedValue.Value.ToString();
// read the reader for the currentAttribute value
if (reader.DoesFieldExist(currentAttribParamValue))
{
var dbRecordValue = reader[currentAttribParamValue] == DBNull.Value ? null : reader[currentAttribParamValue];
// set it in the property
currentProperty.SetValue(val, dbRecordValue, null);
}
break;
}
}
}
}
DynamicMethods or ExpressionTrees will be much* faster than reflection. You could build a cache of all property getter/setters for a type, and then cache that information in a Dictionary (or ConcurrentDictionary) with type as the key.
Expression Tree Basics
Dynamic Methods
Flow
Discover type information (e.g. on app startup).
Compile dynamic methods for each property (do all properties at once).
Store those methods in a metadata class (example follows).
Cache the metadata somewhere (even a static field is fine, as long as access is synchronized). Use the type as the key.
Get the metadata for the type when needed.
Find the appropriate getter/setter.
Invoke, passing the instance on which you wish to act.
// Metadata for a type
public sealed class TypeMetadata<T> {
// The compiled getters for the type; the property name is the key
public Dictionary<string, Func<T, object>> Getters {
get;
set;
}
// The compiled setters for the type; the property name is the key
public Dictionary<string, Action<T, object>> Setters {
get;
set;
}
}
// rough invocation flow
var type = typeof( T);
var metadata = _cache[type];
var propertyName = "MyProperty";
var setter = metadata[propertyName];
var instance = new T();
var value = 12345;
setter( instance, value );
Example Setter
Excerpted from Dynamic Method Implementation (good article on the subject).
I can't vouch that this exact code works, but I've written very similar code myself. If you aren't comfortable with IL, definitely consider an expression tree instead.
public static LateBoundPropertySet CreateSet(PropertyInfo property)
{
var method = new DynamicMethod("Set" + property.Name, null, new[] { typeof(object), typeof(object) }, true);
var gen = method.GetILGenerator();
var sourceType = property.DeclaringType;
var setter = property.GetSetMethod(true);
gen.Emit(OpCodes.Ldarg_0); // Load input to stack
gen.Emit(OpCodes.Castclass, sourceType); // Cast to source type
gen.Emit(OpCodes.Ldarg_1); // Load value to stack
gen.Emit(OpCodes.Unbox_Any, property.PropertyType); // Unbox the value to its proper value type
gen.Emit(OpCodes.Callvirt, setter); // Call the setter method
gen.Emit(OpCodes.Ret);
var result = (LateBoundPropertySet)method.CreateDelegate(typeof(LateBoundPropertySet));
return result;
}
*25-100x faster in my experience
Reflection is notoriously slow in loops, so some kind of caching would probably help. But to decide what to cache, you should measure. As the famous saying goes: "premature optimization is the root of all evil"; you should make sure that you really need to optimize and what exactly to optimize.
For a more concrete advice, attributes are attached at compile time, so you could cache a type and a list of its propertyInfos for example.
I also had similar problem once - reflection is extreemely slow.
I used caching, like you are planning and performance grow more than 10 times. It was never again be a bottleneck in performance.
I've created similar logic before where I've cached an 'execution plan' for each type encountered. It was definitely faster for subsequent runs but you would have to profile your scenario to see whether it's worth the extra code complexity and memory usage.
I can already hear the close vote clicks... lol, oh well.
Ok so I wrote a method that took a Dictionary but then I got this idea to just pass an anonymous type instead so the method calls are less verbose, and then I just convert it to a Dictionary in the method.
However, after this update the compiler is not going to point out to me any calls that are still passing a dictionary since the parameter is just an object.
So I just started wondering if there's a way to enforce the type as anonymous? I actually feel fairly certain the answer is no and if someone just wants to post an answer that simply says "No" (followed by enough characters to be accepted as an answer... and perhaps letting me know how ridiculous my request is while you're at it as well) then I will happily mark that as the answer.
Was just curious enough I had to ask though. Don't hate me for it! :)
No, you can't have a method that takes in an anonymous type - but you can use object or dynamic as cl0ud wrote.
However, the reason on why you would want such a thing is not clear to me. You say to want to make the method call less verbose - but instead of paying the cost of typing in a few more letters and pressing ctrl+space you are subjecting the users of this method to potential runtime exceptions that should have been avoided by throwing compile time exceptions.
Needless to say that's basically throwing away the benefits of the fact that c# is a strongly type language.
Use dynamic if you don't know the type of object before execution
Well, there are a few cons and pros of using Dictionary here (mostly pros)
Pros:
It doesn't require additional logics
You're using benefits of C# as strongly typed language and type check exceptions are thrown at compile time
It is efficient
Cons:
It requires to write more code and is less flexible
If you have tons of calls where you pass dictionaries and performance is not your main concern you might want to create another overload for your method that accepts anonymous object, checks it, and creates a dictionary out of it:
public void MyMethod(object obj)
{
if (!obj.IsAnonymousType())
{
throw new ArgumentException($"Object of this type is not supported!");
}
MyMethod(obj.ToDictionary<int>());
}
public void MyMethod(IDictionary<string, int> dict)
{
// your code here...
}
...
public static class ObjHelper
{
public static IDictionary<string, T> ToDictionary<T>(this object obj)
{
var objType = obj.GetType();
// This call is optimized by compiler
var props = objType.GetProperties();
if (typeof(T) == typeof(object))
{
// we don't need to check if property is of certain type
return props?.ToDictionary(p => p.Name, p => (T)p.GetValue(obj)) ?? new Dictionary<string, T>();
}
// It will ignore all types except of T
return props?.Where(p => p.PropertyType == typeof(T)).ToDictionary(p => p.Name, p => (T)p.GetValue(obj)) ?? new Dictionary<string, T>();
}
public static bool IsAnonymousType(this object obj)
{
var type = obj.GetType();
if (type == null)
{
throw new ArgumentNullException("type");
}
return Attribute.IsDefined(type, typeof(CompilerGeneratedAttribute), false)
&& type.IsGenericType && type.Name.Contains("AnonymousType")
&& (type.Name.StartsWith("<>") || type.Name.StartsWith("VB$"))
&& (type.Attributes & TypeAttributes.NotPublic) == TypeAttributes.NotPublic;
}
}
And call it:
MyMethod(new
{
foo = 15,
bar = 8
})
Let's compare to normal dict call:
MyMethod(new Dictionary<string, int>()
{
{ "foo", 15 },
{ "bar", 8 },
})
Average performance for 100000 operations in ms:
call with anonymous class: 270
call with Dictionary: 10
I am trying to improve performance in the code below and kinda know how but not sure which is the best approach.
The first hit will take longer but subsequent hits should be quicker. Now, I could cache T (where T is a class) and then check the cache to see if "T" exists, if so - go ahead and get its related information (NamedArguments) and go through each of the NamedArguments and finally if the criteria matches, go ahead and set the value of the current property.
I just want to make it more efficient and performant. Any ideas?
var myProps = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static).Where(prop => Attribute.IsDefined(prop, typeof(MyCustomAttribute)) && prop.CanWrite && prop.GetSetMethod() != null);
foreach (var currentProperty in myProps)
{
foreach (var currentAttributeForProperty in currentProperty.GetCustomAttributesData())
{
foreach (var currentNamedArgument in currentAttributeForProperty.NamedArguments)
{
if (string.Equals(currentNamedArgument.MemberInfo.Name, "PropName", StringComparison.OrdinalIgnoreCase))
{
currentAttribParamValue = currentNamedArgument.TypedValue.Value == null ? null : currentNamedArgument.TypedValue.Value.ToString();
// read the reader for the currentAttribute value
if (reader.DoesFieldExist(currentAttribParamValue))
{
var dbRecordValue = reader[currentAttribParamValue] == DBNull.Value ? null : reader[currentAttribParamValue];
// set it in the property
currentProperty.SetValue(val, dbRecordValue, null);
}
break;
}
}
}
}
DynamicMethods or ExpressionTrees will be much* faster than reflection. You could build a cache of all property getter/setters for a type, and then cache that information in a Dictionary (or ConcurrentDictionary) with type as the key.
Expression Tree Basics
Dynamic Methods
Flow
Discover type information (e.g. on app startup).
Compile dynamic methods for each property (do all properties at once).
Store those methods in a metadata class (example follows).
Cache the metadata somewhere (even a static field is fine, as long as access is synchronized). Use the type as the key.
Get the metadata for the type when needed.
Find the appropriate getter/setter.
Invoke, passing the instance on which you wish to act.
// Metadata for a type
public sealed class TypeMetadata<T> {
// The compiled getters for the type; the property name is the key
public Dictionary<string, Func<T, object>> Getters {
get;
set;
}
// The compiled setters for the type; the property name is the key
public Dictionary<string, Action<T, object>> Setters {
get;
set;
}
}
// rough invocation flow
var type = typeof( T);
var metadata = _cache[type];
var propertyName = "MyProperty";
var setter = metadata[propertyName];
var instance = new T();
var value = 12345;
setter( instance, value );
Example Setter
Excerpted from Dynamic Method Implementation (good article on the subject).
I can't vouch that this exact code works, but I've written very similar code myself. If you aren't comfortable with IL, definitely consider an expression tree instead.
public static LateBoundPropertySet CreateSet(PropertyInfo property)
{
var method = new DynamicMethod("Set" + property.Name, null, new[] { typeof(object), typeof(object) }, true);
var gen = method.GetILGenerator();
var sourceType = property.DeclaringType;
var setter = property.GetSetMethod(true);
gen.Emit(OpCodes.Ldarg_0); // Load input to stack
gen.Emit(OpCodes.Castclass, sourceType); // Cast to source type
gen.Emit(OpCodes.Ldarg_1); // Load value to stack
gen.Emit(OpCodes.Unbox_Any, property.PropertyType); // Unbox the value to its proper value type
gen.Emit(OpCodes.Callvirt, setter); // Call the setter method
gen.Emit(OpCodes.Ret);
var result = (LateBoundPropertySet)method.CreateDelegate(typeof(LateBoundPropertySet));
return result;
}
*25-100x faster in my experience
Reflection is notoriously slow in loops, so some kind of caching would probably help. But to decide what to cache, you should measure. As the famous saying goes: "premature optimization is the root of all evil"; you should make sure that you really need to optimize and what exactly to optimize.
For a more concrete advice, attributes are attached at compile time, so you could cache a type and a list of its propertyInfos for example.
I also had similar problem once - reflection is extreemely slow.
I used caching, like you are planning and performance grow more than 10 times. It was never again be a bottleneck in performance.
I've created similar logic before where I've cached an 'execution plan' for each type encountered. It was definitely faster for subsequent runs but you would have to profile your scenario to see whether it's worth the extra code complexity and memory usage.
I've ran into an issue where code classes outside of my control use strings that are null so when they become referenced for example, "string.Length", causes an error. Rather than write a check for the possible 100 fields on average, with nested classes, I thought maybe I could create something easier. I had an idea...
If you've done any research into copying objects PropertyCopy, along with a few others, is an extremely common find. I currently use the class mentioned above. I was wondering if it could be modified to simply go:
if stringPropertyValue is null then set stringPropertyValue equal to string.Empty.
My understanding is limited. I've been doing research to solve my issue but no real good ideas. Can my idea work? Is there a better way? How would it be done if it could?
Update:
Based on a response below I have created this class which I am currently going to use.
public static void DenullifyStringsToEmpty<T>(this T instance)
{
//handle properties
foreach (var filteredProperties in instance.GetType().GetProperties().Where(p =>
(p.PropertyType.IsClass || p.PropertyType.IsInterface || p.PropertyType == typeof(string))))
{
if (filteredProperties.PropertyType == typeof(string))
{
if (filteredProperties.GetValue(instance, null) == null)
{
filteredProperties.SetValue(instance, string.Empty, null);
}
}
else
{
filteredProperties.GetValue(instance, null).DenullifyStringsToEmpty();
}
}
//handle fields
foreach (var filteredFields in instance.GetType().GetFields().Where(f =>
(f.FieldType.IsClass || f.FieldType.IsInterface || f.FieldType == typeof(string))))
{
if (filteredFields.FieldType == typeof(string))
{
if (filteredFields.GetValue(instance) == null)
{
filteredFields.SetValue(instance, string.Empty);
}
}
else
{
filteredFields.GetValue(instance).DenullifyStringsToEmpty();
}
}
}
I know that reflection can be heavy and until we have an issue I think this solution will work great. This is an extension (thanks to the comments below).
Thanks for the input.
Couldn't you just create a simple extension method?
public static string NullToEmpty(this string possibleNullString)
{
return possibleNullString ?? string.Empty;
}
Use this, when accessing the string properties of that third party classes, e.g.:
var length = instanceOfThirdPartyClass.StringProperty.NullToEmpty().Length;
Update:
Now that I understand what you want ;-)
Have a look at this:
public static void DenullStringProperties<T>(this T instance)
{
foreach(var propertyInfo in instance.GetType().GetProperties().
Where(p => p.PropertyType == typeof(string))
{
var value = propertyInfo.GetValue(instance, null);
if(value == null)
value = string.Empty;
propertyInfo.SetValue(instance, value, null);
}
}
You could call it like this:
instanceOfThirdPartyClass.DenullStringProperties();
But I still think you should go with the first approach, because I really don't see a reason to do such heavy lifting during runtime (reflection isn't cheap), just because you are lazy about typing during development :) Additionally, you can't be sure that the properties will stay non null after you have called DenullStringProperties (multi-threading, calls to methods of the object, ...). The first approach checks for null and handles it just as it is needed.
Note: This question was asked before the introduction of the .? operator in C# 6 / Visual Studio 2015.
We've all been there, we have some deep property like cake.frosting.berries.loader that we need to check if it's null so there's no exception. The way to do is is to use a short-circuiting if statement
if (cake != null && cake.frosting != null && cake.frosting.berries != null) ...
This is not exactly elegant, and there should perhaps be an easier way to check the entire chain and see if it comes up against a null variable/property.
Is it possible using some extension method or would it be a language feature, or is it just a bad idea?
We have considered adding a new operation "?." to the language that has the semantics you want. (And it has been added now; see below.) That is, you'd say
cake?.frosting?.berries?.loader
and the compiler would generate all the short-circuiting checks for you.
It didn't make the bar for C# 4. Perhaps for a hypothetical future version of the language.
Update (2014):
The ?. operator is now planned for the next Roslyn compiler release. Note that there is still some debate over the exact syntactic and semantic analysis of the operator.
Update (July 2015): Visual Studio 2015 has been released and ships with a C# compiler that supports the null-conditional operators ?. and ?[].
I got inspired by this question to try and find out how this kind of deep null checking can be done with an easier / prettier syntax using expression trees. While I do agree with the answers stating that it might be a bad design if you often need to access instances deep in the hierarchy, I also do think that in some cases, such as data presentation, it can be very useful.
So I created an extension method, that will allow you to write:
var berries = cake.IfNotNull(c => c.Frosting.Berries);
This will return the Berries if no part of the expression is null. If null is encountered, null is returned. There are some caveats though, in the current version it will only work with simple member access, and it only works on .NET Framework 4, because it uses the MemberExpression.Update method, which is new in v4. This is the code for the IfNotNull extension method:
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace dr.IfNotNullOperator.PoC
{
public static class ObjectExtensions
{
public static TResult IfNotNull<TArg,TResult>(this TArg arg, Expression<Func<TArg,TResult>> expression)
{
if (expression == null)
throw new ArgumentNullException("expression");
if (ReferenceEquals(arg, null))
return default(TResult);
var stack = new Stack<MemberExpression>();
var expr = expression.Body as MemberExpression;
while(expr != null)
{
stack.Push(expr);
expr = expr.Expression as MemberExpression;
}
if (stack.Count == 0 || !(stack.Peek().Expression is ParameterExpression))
throw new ApplicationException(String.Format("The expression '{0}' contains unsupported constructs.",
expression));
object a = arg;
while(stack.Count > 0)
{
expr = stack.Pop();
var p = expr.Expression as ParameterExpression;
if (p == null)
{
p = Expression.Parameter(a.GetType(), "x");
expr = expr.Update(p);
}
var lambda = Expression.Lambda(expr, p);
Delegate t = lambda.Compile();
a = t.DynamicInvoke(a);
if (ReferenceEquals(a, null))
return default(TResult);
}
return (TResult)a;
}
}
}
It works by examining the expression tree representing your expression, and evaluating the parts one after the other; each time checking that the result is not null.
I am sure this could be extended so that other expressions than MemberExpression is supported. Consider this as proof-of-concept code, and please keep in mind that there will be a performance penalty by using it (which will probably not matter in many cases, but don't use it in a tight loop :-) )
I've found this extension to be quite useful for deep nesting scenarios.
public static R Coal<T, R>(this T obj, Func<T, R> f)
where T : class
{
return obj != null ? f(obj) : default(R);
}
It's an idea I derrived from the null coalescing operator in C# and T-SQL. The nice thing is that the return type is always the return type of the inner property.
That way you can do this:
var berries = cake.Coal(x => x.frosting).Coal(x => x.berries);
...or a slight variation of the above:
var berries = cake.Coal(x => x.frosting, x => x.berries);
It's not the best syntax I know, but it does work.
Besides violating the Law of Demeter, as Mehrdad Afshari has already pointed out, it seems to me you need "deep null checking" for decision logic.
This is most often the case when you want to replace empty objects with default values. In this case you should consider implementing the Null Object Pattern. It acts as a stand-in for a real object, providing default values and "non-action" methods.
Update: Starting with Visual Studio 2015, the C# compiler (language version 6) now recognizes the ?. operator, which makes "deep null checking" a breeze. See this answer for details.
Apart from re-designing your code, like
this deleted answer suggested,
another (albeit terrible) option would be to use a try…catch block to see if a NullReferenceException occurs sometime during that deep property lookup.
try
{
var x = cake.frosting.berries.loader;
...
}
catch (NullReferenceException ex)
{
// either one of cake, frosting, or berries was null
...
}
I personally wouldn't do this for the following reasons:
It doesn't look nice.
It uses exception handling, which should target exceptional situations and not something that you expect to happen often during the normal course of operation.
NullReferenceExceptions should probably never be caught explicitly. (See this question.)
So is it possible using some extension method or would it be a language feature, [...]
This would almost certainly have to be a language feature (which is available in C# 6 in the form of the .? and ?[] operators), unless C# already had more sophisticated lazy evaluation, or unless you want to use reflection (which probably also isn't a good idea for reasons of performance and type-safety).
Since there's no way to simply pass cake.frosting.berries.loader to a function (it would be evaluated and throw a null reference exception), you would have to implement a general look-up method in the following way: It takes in an objects and the names of properties to look up:
static object LookupProperty( object startingPoint, params string[] lookupChain )
{
// 1. if 'startingPoint' is null, return null, or throw an exception.
// 2. recursively look up one property/field after the other from 'lookupChain',
// using reflection.
// 3. if one lookup is not possible, return null, or throw an exception.
// 3. return the last property/field's value.
}
...
var x = LookupProperty( cake, "frosting", "berries", "loader" );
(Note: code edited.)
You quickly see several problems with such an approach. First, you don't get any type safety and possible boxing of property values of a simple type. Second, you can either return null if something goes wrong, and you will have to check for this in your calling function, or you throw an exception, and you're back to where you started. Third, it might be slow. Fourth, it looks uglier than what you started with.
[...], or is it just a bad idea?
I'd either stay with:
if (cake != null && cake.frosting != null && ...) ...
or go with the above answer by Mehrdad Afshari.
P.S.: Back when I wrote this answer, I obviously didn't consider expression trees for lambda functions; see e.g. #driis' answer for a solution in this direction. It's also based on a kind of reflection and thus might not perform quite as well as a simpler solution (if (… != null & … != null) …), but it may be judged nicer from a syntax point-of-view.
While driis' answer is interesting, I think it's a bit too expensive performance wise. Rather than compiling many delegates, I'd prefer to compile one lambda per property path, cache it and then reinvoke it many types.
NullCoalesce below does just that, it returns a new lambda expression with null checks and a return of default(TResult) in case any path is null.
Example:
NullCoalesce((Process p) => p.StartInfo.FileName)
Will return an expression
(Process p) => (p != null && p.StartInfo != null ? p.StartInfo.FileName : default(string));
Code:
static void Main(string[] args)
{
var converted = NullCoalesce((MethodInfo p) => p.DeclaringType.Assembly.Evidence.Locked);
var converted2 = NullCoalesce((string[] s) => s.Length);
}
private static Expression<Func<TSource, TResult>> NullCoalesce<TSource, TResult>(Expression<Func<TSource, TResult>> lambdaExpression)
{
var test = GetTest(lambdaExpression.Body);
if (test != null)
{
return Expression.Lambda<Func<TSource, TResult>>(
Expression.Condition(
test,
lambdaExpression.Body,
Expression.Default(
typeof(TResult)
)
),
lambdaExpression.Parameters
);
}
return lambdaExpression;
}
private static Expression GetTest(Expression expression)
{
Expression container;
switch (expression.NodeType)
{
case ExpressionType.ArrayLength:
container = ((UnaryExpression)expression).Operand;
break;
case ExpressionType.MemberAccess:
if ((container = ((MemberExpression)expression).Expression) == null)
{
return null;
}
break;
default:
return null;
}
var baseTest = GetTest(container);
if (!container.Type.IsValueType)
{
var containerNotNull = Expression.NotEqual(
container,
Expression.Default(
container.Type
)
);
return (baseTest == null ?
containerNotNull :
Expression.AndAlso(
baseTest,
containerNotNull
)
);
}
return baseTest;
}
One option is to use the Null Object Patten, so instead of having null when you don’t have a cake, you have a NullCake that returns a NullFosting etc. Sorry I am not very good at explaining this but other people are, see
An example of the Null Object Patten usage
The wikipedai write up on the Null Object Patten
I too have often wished for a simpler syntax! It gets especially ugly when you have method-return-values that might be null, because then you need extra variables (for example: cake.frosting.flavors.FirstOrDefault().loader)
However, here's a pretty decent alternative that I use: create an Null-Safe-Chain helper method. I realize that this is pretty similar to #John's answer above (with the Coal extension method) but I find it's more straightforward and less typing. Here's what it looks like:
var loader = NullSafe.Chain(cake, c=>c.frosting, f=>f.berries, b=>b.loader);
Here's the implementation:
public static TResult Chain<TA,TB,TC,TResult>(TA a, Func<TA,TB> b, Func<TB,TC> c, Func<TC,TResult> r)
where TA:class where TB:class where TC:class {
if (a == null) return default(TResult);
var B = b(a);
if (B == null) return default(TResult);
var C = c(B);
if (C == null) return default(TResult);
return r(C);
}
I also created several overloads (with 2 to 6 parameters), as well as overloads that allow the chain to end with a value-type or default. This works really well for me!
There is Maybe codeplex project that Implements
Maybe or IfNotNull using lambdas for deep expressions in C#
Example of use:
int? CityId= employee.Maybe(e=>e.Person.Address.City);
The link was suggested in a similar question How to check for nulls in a deep lambda expression?
As suggested in John Leidegren's answer, one approach to work-around this is to use extension methods and delegates. Using them could look something like this:
int? numberOfBerries = cake
.NullOr(c => c.Frosting)
.NullOr(f => f.Berries)
.NullOr(b => b.Count());
The implementation is messy because you need to get it to work for value types, reference types and nullable value types. You can find a complete implementation in Timwi's answer to What is the proper way to check for null values?.
Or you may use reflection :)
Reflection function:
public Object GetPropValue(String name, Object obj)
{
foreach (String part in name.Split('.'))
{
if (obj == null) { return null; }
Type type = obj.GetType();
PropertyInfo info = type.GetProperty(part);
if (info == null) { return null; }
obj = info.GetValue(obj, null);
}
return obj;
}
Usage:
object test1 = GetPropValue("PropertyA.PropertyB.PropertyC",obj);
My Case(return DBNull.Value instead of null in reflection function):
cmd.Parameters.AddWithValue("CustomerContactEmail", GetPropValue("AccountingCustomerParty.Party.Contact.ElectronicMail.Value", eInvoiceType));
Try this code:
/// <summary>
/// check deep property
/// </summary>
/// <param name="obj">instance</param>
/// <param name="property">deep property not include instance name example "A.B.C.D.E"</param>
/// <returns>if null return true else return false</returns>
public static bool IsNull(this object obj, string property)
{
if (string.IsNullOrEmpty(property) || string.IsNullOrEmpty(property.Trim())) throw new Exception("Parameter : property is empty");
if (obj != null)
{
string[] deep = property.Split('.');
object instance = obj;
Type objType = instance.GetType();
PropertyInfo propertyInfo;
foreach (string p in deep)
{
propertyInfo = objType.GetProperty(p);
if (propertyInfo == null) throw new Exception("No property : " + p);
instance = propertyInfo.GetValue(instance, null);
if (instance != null)
objType = instance.GetType();
else
return true;
}
return false;
}
else
return true;
}
I posted this last night and then a friend pointed me to this question. Hope it helps. You can then do something like this:
var color = Dis.OrDat<string>(() => cake.frosting.berries.color, "blue");
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
namespace DeepNullCoalescence
{
public static class Dis
{
public static T OrDat<T>(Expression<Func><T>> expr, T dat)
{
try
{
var func = expr.Compile();
var result = func.Invoke();
return result ?? dat; //now we can coalesce
}
catch (NullReferenceException)
{
return dat;
}
}
}
}
Read the full blog post here.
The same friend also suggested that you watch this.
I slightly modified the code from here to make it work for the question asked:
public static class GetValueOrDefaultExtension
{
public static TResult GetValueOrDefault<TSource, TResult>(this TSource source, Func<TSource, TResult> selector)
{
try { return selector(source); }
catch { return default(TResult); }
}
}
And yes, this is probably not the optimal solution due to try/catch performance implications but it works :>
Usage:
var val = cake.GetValueOrDefault(x => x.frosting.berries.loader);
Where you need to achieve this, do this:
Usage
Color color = someOrder.ComplexGet(x => x.Customer.LastOrder.Product.Color);
or
Color color = Complex.Get(() => someOrder.Customer.LastOrder.Product.Color);
Helper class implementation
public static class Complex
{
public static T1 ComplexGet<T1, T2>(this T2 root, Func<T2, T1> func)
{
return Get(() => func(root));
}
public static T Get<T>(Func<T> func)
{
try
{
return func();
}
catch (Exception)
{
return default(T);
}
}
}
I like approach taken by Objective-C:
"The Objective-C language takes another approach to this problem and does not invoke methods on nil but instead returns nil for all such invocations."
if (cake.frosting.berries != null)
{
var str = cake.frosting.berries...;
}