Serialize an expression with an variable - c#

I wrote some classes to serialize System.Linq.Expressions to DataContracts to be able to send via WCF. It works quite good nice. the problem is when i want to serialize an expression that has a variable in it. here is an example to explain the problem:
public class Foo
{
public string Name { get; set; }
}
// CASE 1
Expression<Func<Foo, bool>> lambda = foo => foo.Name == "Test";
Console.WriteLine(lambda);
// OUTPUT: foo => (foo.Name == "Test")
// CASE 2
var variable = "Test";
lambda = foo => foo.Name == variable;
this.AssertExpression(lambda, "Class Lambda expression with variable.");
// OUTPUT: foo => (foo.Name == value(MyTest+<>c__DisplayClass0).variable)
i am not having trouble to serialize the CASE 2 expression, but the the data i serialize is useless, since on the service side, there is nothing to resolve value(MyTest+<>c__DisplayClass0).variable
so i need to resolve the variables before i serialize that expression so that the CASE 2 expression serializes to same result as CASE1

Sorry for the VB, but the following extract is the bit of code I meant in my comment. I don't think it covers all the bases (i.e. it may not be drilling down far enough so make sure you test it) but for simple most examples it works:
The code is based on this MSDN Expression Visitor example:
class CustomExpressionWalker<TSource> : ExpressionVisitor
{
protected override Expression VisitMemberAccess(MemberExpression m)
{
if (m.Member.DeclaringType != typeof(TSource))
{
// We are accessing a member/variable on a class
// We need to descend the tree through the navigation properties and eventually derive a constant expression
return this.VisitMemberAccess(m, m.Type);
}
throw new NotImplementedException();
}
protected Expression VisitMemberAccess(MemberExpression m, Type expectedType)
{
if (m.Expression.NodeType == ExpressionType.Constant)
{
// We are at the end of the member expression
// i.e. MyClass.Something.Something.Value <-- we're at the Value part now
ConstantExpression constant = (ConstantExpression)m.Expression;
return Expression.Constant(m.Expression.Type.GetFields().Single(n => n.FieldType == expectedType && m.Member.Name.Contains(n.Name)).GetValue(constant.Value));
}
else if (m.Member.DeclaringType == typeof(TSource))
{
// I'm unsure of your current implementation but the original Member access
// regarding serializing the expression, but if the code reaches here a nested
// MemberAccess has landed on a Property/variable of type TSource, so you'll need
// to decide whether to serialize here or not. For example, if TSource was of
// type "myClass", it could be
// (myOtherClass x) => x.myClass
throw new NotImplementedException();
}
else if (m.Member.DeclaringType == typeof(Nullable))
{
// never got round to implementing this as we don't need it yet
// if you want to deal with Nullable<T> you're going to have to
// examine the logic here
throw new NotImplementedException();
}
else
{
// continue walking the member access until we derive the constant
return this.VisitMemberAccess((MemberExpression)m.Expression, expectedType);
}
}
}
Hope this helps!
EDIT: The original issue I had was that I didn't continue walking the tree when the MemberAccess was a non TSource class, the above logic should actually recursively root those cases out so ignore my original comment. I've left in the Nullable<T> clause (on the else if) statement as I don't think the existing logic will cover those cases, it may also struggle with Generic classes.
That said, this should put you in good stead. If you're not using the Expression Visitor, can you provide some more details/code?
Good luck!

Related

In c#, how do I know what subclass an object is when stored as the parent? [duplicate]

I've seen many people use the following code:
Type t = obj1.GetType();
if (t == typeof(int))
// Some code here
But I know you could also do this:
if (obj1.GetType() == typeof(int))
// Some code here
Or this:
if (obj1 is int)
// Some code here
Personally, I feel the last one is the cleanest, but is there something I'm missing? Which one is the best to use, or is it personal preference?
All are different.
typeof takes a type name (which you specify at compile time).
GetType gets the runtime type of an instance.
is returns true if an instance is in the inheritance tree.
Example
class Animal { }
class Dog : Animal { }
void PrintTypes(Animal a) {
Console.WriteLine(a.GetType() == typeof(Animal)); // false
Console.WriteLine(a is Animal); // true
Console.WriteLine(a.GetType() == typeof(Dog)); // true
Console.WriteLine(a is Dog); // true
}
Dog spot = new Dog();
PrintTypes(spot);
What about typeof(T)? Is it also resolved at compile time?
Yes. T is always what the type of the expression is. Remember, a generic method is basically a whole bunch of methods with the appropriate type. Example:
string Foo<T>(T parameter) { return typeof(T).Name; }
Animal probably_a_dog = new Dog();
Dog definitely_a_dog = new Dog();
Foo(probably_a_dog); // this calls Foo<Animal> and returns "Animal"
Foo<Animal>(probably_a_dog); // this is exactly the same as above
Foo<Dog>(probably_a_dog); // !!! This will not compile. The parameter expects a Dog, you cannot pass in an Animal.
Foo(definitely_a_dog); // this calls Foo<Dog> and returns "Dog"
Foo<Dog>(definitely_a_dog); // this is exactly the same as above.
Foo<Animal>(definitely_a_dog); // this calls Foo<Animal> and returns "Animal".
Foo((Animal)definitely_a_dog); // this does the same as above, returns "Animal"
Use typeof when you want to get the type at compilation time. Use GetType when you want to get the type at execution time. There are rarely any cases to use is as it does a cast and, in most cases, you end up casting the variable anyway.
There is a fourth option that you haven't considered (especially if you are going to cast an object to the type you find as well); that is to use as.
Foo foo = obj as Foo;
if (foo != null)
// your code here
This only uses one cast whereas this approach:
if (obj is Foo)
Foo foo = (Foo)obj;
requires two.
Update (Jan 2020):
As of C# 7+, you can now cast inline, so the 'is' approach can now be done in one cast as well.
Example:
if(obj is Foo newLocalFoo)
{
// For example, you can now reference 'newLocalFoo' in this local scope
Console.WriteLine(newLocalFoo);
}
1.
Type t = typeof(obj1);
if (t == typeof(int))
This is illegal, because typeof only works on types, not on variables. I assume obj1 is a variable. So, in this way typeof is static, and does its work at compile time instead of runtime.
2.
if (obj1.GetType() == typeof(int))
This is true if obj1 is exactly of type int. If obj1 derives from int, the if condition will be false.
3.
if (obj1 is int)
This is true if obj1 is an int, or if it derives from a class called int, or if it implements an interface called int.
Type t = typeof(obj1);
if (t == typeof(int))
// Some code here
This is an error. The typeof operator in C# can only take type names, not objects.
if (obj1.GetType() == typeof(int))
// Some code here
This will work, but maybe not as you would expect. For value types, as you've shown here, it's acceptable, but for reference types, it would only return true if the type was the exact same type, not something else in the inheritance hierarchy. For instance:
class Animal{}
class Dog : Animal{}
static void Foo(){
object o = new Dog();
if(o.GetType() == typeof(Animal))
Console.WriteLine("o is an animal");
Console.WriteLine("o is something else");
}
This would print "o is something else", because the type of o is Dog, not Animal. You can make this work, however, if you use the IsAssignableFrom method of the Type class.
if(typeof(Animal).IsAssignableFrom(o.GetType())) // note use of tested type
Console.WriteLine("o is an animal");
This technique still leaves a major problem, though. If your variable is null, the call to GetType() will throw a NullReferenceException. So to make it work correctly, you'd do:
if(o != null && typeof(Animal).IsAssignableFrom(o.GetType()))
Console.WriteLine("o is an animal");
With this, you have equivalent behavior of the is keyword. Hence, if this is the behavior you want, you should use the is keyword, which is more readable and more efficient.
if(o is Animal)
Console.WriteLine("o is an animal");
In most cases, though, the is keyword still isn't what you really want, because it's usually not enough just to know that an object is of a certain type. Usually, you want to actually use that object as an instance of that type, which requires casting it too. And so you may find yourself writing code like this:
if(o is Animal)
((Animal)o).Speak();
But that makes the CLR check the object's type up to two times. It will check it once to satisfy the is operator, and if o is indeed an Animal, we make it check again to validate the cast.
It's more efficient to do this instead:
Animal a = o as Animal;
if(a != null)
a.Speak();
The as operator is a cast that won't throw an exception if it fails, instead returning null. This way, the CLR checks the object's type just once, and after that, we just need to do a null check, which is more efficient.
But beware: many people fall into a trap with as. Because it doesn't throw exceptions, some people think of it as a "safe" cast, and they use it exclusively, shunning regular casts. This leads to errors like this:
(o as Animal).Speak();
In this case, the developer is clearly assuming that o will always be an Animal, and as long as their assumption is correct, everything works fine. But if they're wrong, then what they end up with here is a NullReferenceException. With a regular cast, they would have gotten an InvalidCastException instead, which would have more correctly identified the problem.
Sometimes, this bug can be hard to find:
class Foo{
readonly Animal animal;
public Foo(object o){
animal = o as Animal;
}
public void Interact(){
animal.Speak();
}
}
This is another case where the developer is clearly expecting o to be an Animal every time, but this isn't obvious in the constructor, where the as cast is used. It's not obvious until you get to the Interact method, where the animal field is expected to be positively assigned. In this case, not only do you end up with a misleading exception, but it isn't thrown until potentially much later than when the actual error occurred.
In summary:
If you only need to know whether or not an object is of some type, use is.
If you need to treat an object as an instance of a certain type, but you don't know for sure that the object will be of that type, use as and check for null.
If you need to treat an object as an instance of a certain type, and the object is supposed to be of that type, use a regular cast.
If you're using C# 7, then it is time for an update to Andrew Hare's great answer. Pattern matching has introduced a nice shortcut that gives us a typed variable within the context of the if statement, without requiring a separate declaration/cast and check:
if (obj1 is int integerValue)
{
integerValue++;
}
This looks pretty underwhelming for a single cast like this, but really shines when you have many possible types coming into your routine. The below is the old way to avoid casting twice:
Button button = obj1 as Button;
if (button != null)
{
// do stuff...
return;
}
TextBox text = obj1 as TextBox;
if (text != null)
{
// do stuff...
return;
}
Label label = obj1 as Label;
if (label != null)
{
// do stuff...
return;
}
// ... and so on
Working around shrinking this code as much as possible, as well as avoiding duplicate casts of the same object has always bothered me. The above is nicely compressed with pattern matching to the following:
switch (obj1)
{
case Button button:
// do stuff...
break;
case TextBox text:
// do stuff...
break;
case Label label:
// do stuff...
break;
// and so on...
}
EDIT: Updated the longer new method to use a switch as per Palec's comment.
I had a Type-property to compare to and could not use is (like my_type is _BaseTypetoLookFor), but I could use these:
base_type.IsInstanceOfType(derived_object);
base_type.IsAssignableFrom(derived_type);
derived_type.IsSubClassOf(base_type);
Notice that IsInstanceOfType and IsAssignableFrom return true when comparing the same types, where IsSubClassOf will return false. And IsSubclassOf does not work on interfaces, where the other two do. (See also this question and answer.)
public class Animal {}
public interface ITrainable {}
public class Dog : Animal, ITrainable{}
Animal dog = new Dog();
typeof(Animal).IsInstanceOfType(dog); // true
typeof(Dog).IsInstanceOfType(dog); // true
typeof(ITrainable).IsInstanceOfType(dog); // true
typeof(Animal).IsAssignableFrom(dog.GetType()); // true
typeof(Dog).IsAssignableFrom(dog.GetType()); // true
typeof(ITrainable).IsAssignableFrom(dog.GetType()); // true
dog.GetType().IsSubclassOf(typeof(Animal)); // true
dog.GetType().IsSubclassOf(typeof(Dog)); // false
dog.GetType().IsSubclassOf(typeof(ITrainable)); // false
I prefer is
That said, if you're using is, you're likely not using inheritance properly.
Assume that Person : Entity, and that Animal : Entity. Feed is a virtual method in Entity (to make Neil happy)
class Person
{
// A Person should be able to Feed
// another Entity, but they way he feeds
// each is different
public override void Feed( Entity e )
{
if( e is Person )
{
// feed me
}
else if( e is Animal )
{
// ruff
}
}
}
Rather
class Person
{
public override void Feed( Person p )
{
// feed the person
}
public override void Feed( Animal a )
{
// feed the animal
}
}
I believe the last one also looks at inheritance (e.g. Dog is Animal == true), which is better in most cases.
It depends on what I'm doing. If I need a bool value (say, to determine if I'll cast to an int), I'll use is. If I actually need the type for some reason (say, to pass to some other method) I'll use GetType().
The last one is cleaner, more obvious, and also checks for subtypes. The others do not check for polymorphism.
Used to obtain the System.Type object for a type. A typeof expression takes the following form:
System.Type type = typeof(int);
Example:
public class ExampleClass
{
public int sampleMember;
public void SampleMethod() {}
static void Main()
{
Type t = typeof(ExampleClass);
// Alternatively, you could use
// ExampleClass obj = new ExampleClass();
// Type t = obj.GetType();
Console.WriteLine("Methods:");
System.Reflection.MethodInfo[] methodInfo = t.GetMethods();
foreach (System.Reflection.MethodInfo mInfo in methodInfo)
Console.WriteLine(mInfo.ToString());
Console.WriteLine("Members:");
System.Reflection.MemberInfo[] memberInfo = t.GetMembers();
foreach (System.Reflection.MemberInfo mInfo in memberInfo)
Console.WriteLine(mInfo.ToString());
}
}
/*
Output:
Methods:
Void SampleMethod()
System.String ToString()
Boolean Equals(System.Object)
Int32 GetHashCode()
System.Type GetType()
Members:
Void SampleMethod()
System.String ToString()
Boolean Equals(System.Object)
Int32 GetHashCode()
System.Type GetType()
Void .ctor()
Int32 sampleMember
*/
This sample uses the GetType method to determine the type that is used to contain the result of a numeric calculation. This depends on the storage requirements of the resulting number.
class GetTypeTest
{
static void Main()
{
int radius = 3;
Console.WriteLine("Area = {0}", radius * radius * Math.PI);
Console.WriteLine("The type is {0}",
(radius * radius * Math.PI).GetType()
);
}
}
/*
Output:
Area = 28.2743338823081
The type is System.Double
*/
I found checking if the type of something is equal to something is done by the following:
variableName.GetType() == typeof(int)
if (c is UserControl) c.Enabled = enable;
You can use "typeof()" operator in C# but you need to call the namespace using System.IO; You must use "is" keyword if you wish to check for a type.
Performance test typeof() vs GetType():
using System;
namespace ConsoleApplication1
{
class Program
{
enum TestEnum { E1, E2, E3 }
static void Main(string[] args)
{
{
var start = DateTime.UtcNow;
for (var i = 0; i < 1000000000; i++)
Test1(TestEnum.E2);
Console.WriteLine(DateTime.UtcNow - start);
}
{
var start = DateTime.UtcNow;
for (var i = 0; i < 1000000000; i++)
Test2(TestEnum.E2);
Console.WriteLine(DateTime.UtcNow - start);
}
Console.ReadLine();
}
static Type Test1<T>(T value) => typeof(T);
static Type Test2(object value) => value.GetType();
}
}
Results in debug mode:
00:00:08.4096636
00:00:10.8570657
Results in release mode:
00:00:02.3799048
00:00:07.1797128

Utilizing Funcs within expressions?

Background
I have an example of a test that passes but an error that happens down the pipeline and I'm not sure why. I'd like to figure out what's going on but I'm new to Expression construction and don't want to make any assumptions.
This is for a search filtering mechanism. It uses ServiceStack's PredicateBuilder implementation. I essentially have a list of values that I pass in, and I want it to construct an expression tree. I had previously done this just with Func<T<bool>> but realized that I needed to wind up with Expression<Func<T<bool>>>. Bummer.
The Goal
Search filters built from Re-usable search filter types, which built out of Funcs and Expressions that allows me to pass in a field name from an object along with values I should match on and wind up with something that we can run a Where() statement against.
The Code / Issue
The generic "nullable bool" filter I'm trying -- sets up the acceptable items and returns a func that is meant to help filter:
public class NullableBoolFilter : IGenericSearchFilter<bool?>
{
public Func<bool?, bool> GetFilterFunc(string valuesToProcess)
{
var acceptableValues = new List<bool?>();
if (string.IsNullOrWhiteSpace(valuesToProcess))
{
// all values acceptable
acceptableValues = new List<bool?>{true, false, null};
}
else
{
if (!valuesToProcess.Contains("0") && !valuesToProcess.Contains("1"))
{
throw new ArgumentException("Invalid Nullable boolean filter attribute specified");
}
if (valuesToProcess.Contains("0"))
{
acceptableValues.Add(false);
}
if (valuesToProcess.Contains("1"))
{
acceptableValues.Add(true);
}
}
Func<bool?, bool> returnFunc = delegate(bool? item) { return acceptableValues.Any(x=>x == item); };
return returnFunc;
}
}
Then I have another filter, which inherits from the NullableBoolFilter and attempts to use the Func:
public class ClaimsReportIsMDLFilter : NullableBoolFilter, ISearchFilter<vSEARCH_ClaimsReport>
{
public Expression<Func<vSEARCH_ClaimsReport, bool>> GetExpression(string valuesToProcess)
{
var theFunc = base.GetFilterFunc(valuesToProcess);
Expression<Func<vSEARCH_ClaimsReport, bool>> mdlMatches = item => theFunc(item.IsMDL);
var predicate = PredicateBuilder.False<vSEARCH_ClaimsReport>();
predicate = predicate.Or(mdlMatches);
return predicate;
}
}
The following test passes:
public class ClaimsReportIsMDLFilterTests
{
// ReSharper disable InconsistentNaming
private readonly vSEARCH_ClaimsReport ItemWithMDL = new vSEARCH_ClaimsReport { IsMDL = true };
private readonly vSEARCH_ClaimsReport ItemWithoutMDL = new vSEARCH_ClaimsReport { IsMDL = false };
private readonly vSEARCH_ClaimsReport ItemWithNullMDL = new vSEARCH_ClaimsReport { IsMDL = null };
// ReSharper restore InconsistentNaming
[Fact]
public void WithSearchValueOf1_HidesNonMDLAndNull()
{
var sut = this.GetCompiledExpressionForValues("1");
sut.Invoke(ItemWithMDL).Should().BeTrue();
sut.Invoke(ItemWithoutMDL).Should().BeFalse();
sut.Invoke(ItemWithNullMDL).Should().BeFalse();
}
private Func<vSEARCH_ClaimsReport, bool> GetCompiledExpressionForValues(string searchValue)
{
return new ClaimsReportIsMDLFilter().GetExpression(searchValue).Compile();
}
}
The Problem
When I actually attempt to run this, I receive the error:
variable 'param' of type 'vSEARCH_ClaimsReport' referenced from scope '', but it is not defined
It makes sense to me why this might occur -- at the time it's evaluated, I don't have a real object to pass into the Func. However, I'm confused as to why my tests might pass but this doesn't in actual usage.
Questions
Why might my tests pass but I still receive this error?
How the heck should I begin trying to fix this?
Is there a remotely easy way to take that Func and turn it into an Expression that I can pass a field into?
Do I need to abandon the generic filter idea and have each class manually add expressions to the PredicateBuilder based on input passed in? That's doable, but it seems like the work could be reduced more.
Why might my tests pass [...]
Because your test is simply compiling the expression down into the code that it represents and invoking it. It doesn't need to actually parse the expression tree and look at what the code it represents is doing, it just runs it and ensures that the output is right.
Why might [...] I still receive this error?
Because when you're actually using it, it's not just executing the code; rather it is looking through the expression tree to try to determine what the code is doing so that it can be translated into something else, not so that it can be run as C# code.
Your expression is doing nothing but calling a delegate. There is no way for someone traversing the expression tree to see inside the delegate and know what it's doing. Knowing that you're calling another method isn't something that can be translated into another language.
How the heck should I begin trying to fix this?
You need to generate an Expression from the start, rather than generating a Func and then just creating an Expression that calls it.
Is there a remotely easy way to take that Func and turn it into an Expression that I can pass a field into?
No. You'd need to pull out the IL code of the function, decompile that into C# code, then build up Expression objects to represent that code. That's pretty much just not going to happen.
You're pretty much going to need to have GetFilterFunc return an Expression, to get this to work. Fortunately, this is quite easy to do, given what you have. You simply need to change the method signature and to replace the last two lines with the following:
return item => acceptableValues.Any(x => x == item);
And voila. The lambda can be compiled into an Expression object, rather than a delegate, based on context, so if the return type of the method is an Expression<Func<bool?,bool>> that's what you'll get.
Now, to use this in GetExpression. First off, the PredicateBuilder isn't really doing anything. Adding an OR FALSE to your expression changes nothing meaningful about it. All of that can go. All that leaves us with is using an Expression<Func<bool?,bool>> and changing it into an Expression<Func<vSEARCH_ClaimsReport, bool>> by pulling out a boolean property. To do this is a bit more work for expressions than for delegates. Rather than just invoking the expression, we need to do a tad more work to compose them. We'll want to write a method to do this operation:
public static Expression<Func<TFirstParam, TResult>>
Compose<TFirstParam, TIntermediate, TResult>(
this Expression<Func<TFirstParam, TIntermediate>> first,
Expression<Func<TIntermediate, TResult>> second)
{
var param = Expression.Parameter(typeof(TFirstParam), "param");
var newFirst = first.Body.Replace(first.Parameters[0], param);
var newSecond = second.Body.Replace(second.Parameters[0], newFirst);
return Expression.Lambda<Func<TFirstParam, TResult>>(newSecond, param);
}
And this relies on the use of the following method to replace all instances of one expression with another:
public static Expression Replace(this Expression expression,
Expression searchEx, Expression replaceEx)
{
return new ReplaceVisitor(searchEx, replaceEx).Visit(expression);
}
internal class ReplaceVisitor : ExpressionVisitor
{
private readonly Expression from, to;
public ReplaceVisitor(Expression from, Expression to)
{
this.from = from;
this.to = to;
}
public override Expression Visit(Expression node)
{
return node == from ? to : base.Visit(node);
}
}
What this is doing is replacing all instances of the second expression's parameter with the body of the first expression, effectively inlining that expression into the second. The rest is simply replacing all of the parameters with a new single parameter and wrapping it back up into a lambda.
Now that we have that, our method is quite easy:
public Expression<Func<vSEARCH_ClaimsReport, bool>> GetExpression(
string valuesToProcess)
{
Expression<Func<vSEARCH_ClaimsReport, bool?>> selector =
item => item.IsMDL;
return selector.Compose(base.GetFilterFunc(valuesToProcess));
}

Get actual return type from a Expression<Func<T, object>> instance

I have a method that accepts a Expression<Func<T, object>> instance. I want to get at the actual data type being returned by a specific expression instance, rather than object.
I can get it to work for direct property references, so if I pass in the expression x => x.IntegerProperty I can get a Type reference for an integer. This approach requires converting it to a MemberExpression.
However, I can't get it to work for arbitrary expressions. For instance, if the expression is x => x.IntegerProperty.ToString() I want to get a Type reference for a string. I can't compile this to a MemberExpression, and if I just .Compile() it and check the return type I get "object".
How can I look at the specific expression instance and derive the actual return type?
Something like this might do the trick. It probably doesn't cover every possibility, but it's a start.
public static Type GetObjectType<T>(Expression<Func<T, object>> expr)
{
if ((expr.Body.NodeType == ExpressionType.Convert) ||
(expr.Body.NodeType == ExpressionType.ConvertChecked))
{
var unary = expr.Body as UnaryExpression;
if (unary != null)
return unary.Operand.Type;
}
return expr.Body.Type;
}
While not impossible, this is particularly difficult. It would require walking the expression tree and doing some potentially complex logic. For example, what would you want to see if I passed in the following expression?
Func<bool, object> expr = switch => switch ? 1 : "False";
This method could either return an int or a string.
Now, you might be able to make more headway by offloading some of this logic on the compiler. You could change your method parameter from Func<T, object> to Func<T, TReturn> and use typeof(TReturn) within the method to determine what the compiler decided the return type of the expression was.
Of course, in the case of my example, you'll still be working against object. But, your example of x => x.IntegerProperty.ToString() will yield string, which is what you're looking for.
Bit of a cheeky way (and it involves actually invoking the Func), but you can do this:
using System;
class Program
{
static Func<T,object> MakeFunc<T>()
{
return x => 23;
}
static Type GetReturnType<T>(Func<T,object> f)
{
return f(default(T)).GetType();
}
static void Main(string[] args)
{
Type t = GetReturnType(MakeFunc<string>());
Console.WriteLine(t);
}
}
It's not guaranteed to work in all situations, I should add - particularly if the default(T) isn't a valid parameter to the Func. But it's a potential starting point at least.

Deep null checking, is there a better way?

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

What's the best way to define & access selected properties in C#?

From my recent question, I try to centralize the domain model by including some silly logic in domain interface. However, I found some problem that need to include or exclude some properties from validating.
Basically, I can use expression tree like the following code. Nevertheless, I do not like it because I need to define local variable ("u") each time when I create lambda expression. Do you have any source code that is shorter than me? Moreover, I need some method to quickly access selected properties.
public void IncludeProperties<T>(params Expression<Func<IUser,object>>[] selectedProperties)
{
// some logic to store parameter
}
IncludeProperties<IUser>
(
u => u.ID,
u => u.LogOnName,
u => u.HashedPassword
);
Thanks,
Lambdas are great for many scenarios - but if you don't want them, perhaps simply don't use them? I hate to say it, but simple strings are tried and tested, especially for scenarios like data binding. If you want fast access, you could look at HyperDescriptor, or there are ways of compiling a delegate to the property accessors, or you can build an Expression from the string and compile it (including a cast to object if you want a known signature, rather than calling the (much slower) DynamicInvoke).
Of course, in most cases even crude reflection is fast enough, and isn't the bottleneck.
I suggest starting with the simplest code, and check it is actually too slow before worrying about it being fast. If it isn't too slow, don't change it. Any of the above options would work otherwise.
Another thought; if you are using Expression, you could do something like:
public void IncludeProperties<T>(
Expression<Func<T,object>> selectedProperties)
{
// some logic to store parameter
}
IncludeProperties<IUser>( u => new { u.ID, u.LogOnName, u.HashedPassword });
and then take the expression apart? A bit tidier, at least... here's some sample code showing the deconstruction:
public static void IncludeProperties<T>(
Expression<Func<T, object>> selectedProperties)
{
NewExpression ne = selectedProperties.Body as NewExpression;
if (ne == null) throw new InvalidOperationException(
"Object constructor expected");
foreach (Expression arg in ne.Arguments)
{
MemberExpression me = arg as MemberExpression;
if (me == null || me.Expression != selectedProperties.Parameters[0])
throw new InvalidOperationException(
"Object constructor argument should be a direct member");
Console.WriteLine("Accessing: " + me.Member.Name);
}
}
static void Main()
{
IncludeProperties<IUser>(u => new { u.ID, u.LogOnName, u.HashedPassword });
}
Once you know the MemberInfos (me.Member in the above), building your own lambdas for individual access should be trivial. For example (including a cast to object to get a single signature):
var param = Expression.Parameter(typeof(T), "x");
var memberAccess = Expression.MakeMemberAccess(param, me.Member);
var body = Expression.Convert(memberAccess, typeof(object));
var lambda = Expression.Lambda<Func<T, object>>(body, param);
var func = lambda.Compile();
Here's the shortest expression I can come up with:
public static void IncludeProperties(Expression<Action<IUser>> selectedProperties)
{
// some logic to store parameter
}
public static void S(params object[] props)
{
// dummy method to get to the params syntax
}
[Test]
public void ParamsTest()
{
IncludeProperties(u => S(
u.Id,
u.Name
));
}

Categories