If I have a long list of objects that each has the possibility of returning null within a "Linq where" clause, e.g.
SomeSource.Where(srcItem=>(srcItem.DataMembers["SomeText"].Connection.ConnectedTo as Type1).Handler.ForceInvocation == true));
the indexer can return null and the "as" operator may return null. It is possible that the object does not have a connection (ie. The property is null).
If a null is encountered anywhere, I would like the where clause to return "false" for the item being evaluated. Instead, it aborts with a null reference exception.
It appears to me that this would be contrived to express within a single C# expression. I don't like to create a multi line statement or create a separate func for it.
Is there some use of the null coalescing operator that I'm missing?
You're looking for the .? operator (or is it ?.—one of those, anyway), which does not exist in C# (though it is an often-requested feature, according to Eric Lippert).
The only possible suggestion I have is to write a method that takes an expression and uses it to check for any nulls. But this will come at a performance cost. Anyway, it might look like:
T TryOrDefault<T>(Expression<Func<T>> expression)
{
// Check every MemberExpression within expression one by one,
// looking for any nulls along the way.
// If a null is found, return default(T) or some default value.
// Otherwise...
Func<T> func = expression.Compile();
return func();
}
Using the andand operator from Ruby as inspiration, you could create an extension method that acts as a null guard.
public static U AndAnd<T, U>(this T obj, Func<T, U> func)
{
return obj == null ? default(U) : func(obj);
}
Your original code could then be rewritten as follows:
SomeSource.Where(srcItem => (srcItem.AndAnd(val => val.DataMembers["SomeText"]).AndAnd(val => val.Connection).AndAnd(val => val.ConnectedTo) as Type1).AndAnd(val => val.Handler).AndAnd(val => val.ForceInvocation));
Do be careful when returning non-boolean value types using this method - make sure you are familiar with the values returned by default(U).
create a separate func for it
This is the way to go. Do not be allergic to proper techniques. Methods you create are no more expensive (at runtime, and conceptually) than anonymous methods.
A while ago I wrote a project that mimics AndAnd that relies on DynamicProxy. It works fine, although I've not used it in prod. The only drawback is that it requires all of the members to be virtual or the returned types to be an interface so DynamicProxy can do its magic.
Check it here
https://bitbucket.org/mamadero/andand/overview
Related
According to the Constraints on Type Parameters (C# Programming Guide) documentation it says, and I quote:
When applying the where T : class constraint, avoid the == and !=
operators on the type parameter because these operators will test for
reference identity only, not for value equality. This is the case even
if these operators are overloaded in a type that is used as an
argument. The following code illustrates this point; the output is
false even though the String class overloads the == operator.
With the following example:
public static void OpTest<T>(T s, T t) where T : class
{
System.Console.WriteLine(s == t);
}
static void Main()
{
string s1 = "target";
System.Text.StringBuilder sb = new System.Text.StringBuilder("target");
string s2 = sb.ToString();
OpTest<string>(s1, s2);
}
However, ReSharper (I've just started using the demo/trial version to see if it is any worth to me) gives a hint/tip to do null-checking of parameters like so:
public Node(T type, Index2D index2D, int f, Node<T> parent)
{
if (type == null) throw new ArgumentNullException("type");
if (index2D == null) throw new ArgumentNullException("index2D");
if (parent == null) throw new ArgumentNullException("parent");
}
(T is constrained with where T : class, new())
Can I safely follow ReSharper without running into problems that the C# documentation is trying to tell me to avoid?
Yes, that is fine. The documentation says not to compare two parameters because you're doing a reference comparison. The code ReSharper suggests is just ensuring the reference you've been passed is not null so that is safe to do.
In my opinion the main reason the C# docs recommend you don't do that is because if for example you do == with two strings that were passed as T1 and T2 it will do a reference comparison. Any other time you do stringA == stringB it will do a value comparison with the overload in the string class. It's really just warning against doing these types of comparisons because the operator overload that would normally be used (if you used that operator on two types declared in local scope) is not.
Yes.
Only a very strange implementation of the == operator would make x == null mean something other than ReferenceEquals(x, null). If you are using classes that have such a strange implementation of equality, you have bigger problems than it being inconsistent when checking for null using a generic type argument.
The documentation is telling you that == will use a reference comparison regardless of what the actual type of T is, even if it has overloaded the == operator. In many cases this isn't what users would expect.
In the case of the resharper code it's comparing the variable to null, which you want to be a reference comparison, not a value comparison, so what the documentation is warning you of is the correct behavior here.
You could however make it a bit more explicit by writing something like this, just to be clearer:
if(object.ReferenceEquals(type, null))//...
Yes, it's generally ok to assume that null is a special case, and that it's okay to do == or != on it. This is due, in part at least, to the fact that the recommendation for overriding Equals says that x.Equals(null) should be false.
If you didn't have the T : class constraint, it'd be a different story, since you'd see some possibly-unexpected behavior for structs and nullable structs (you might want to do default(T) instead of null there).
And if you want to be explicit that yes, you know you're comparing the reference to null, you can always use object.ReferenceEquals(x, null) (I'd just go with ==/!=, though).
I would say that this is OK.
null is kinda special, so you are not doing an actual comparison between two reference variables, you are just assuring that the reference variable is not a null reference.
Compare this with, for example, SQL. There you have a completely different syntax for comparing ( a = b) and for the null check (a is null). The guideline is that you should avoid the first, but the second is ok.
I want to be able to call properties on objects that might be null but not explicitly have to check whether they are null or not when calling.
Like this:
var something = someObjectThatMightBeNull.Property;
My idea is to create a method that takes an Expression, something like this:
var something = GetValueSafe(() => someObjectThatMightBeNull.Property);
TResult? GetValueSafe<TResult>(Expression<Func<TResult>> expression)
where TResult : struct
{
// what must I do?
}
What I need to do is to inspect the expression and determine if someObjectThatMightBeNull is null or not. How would I do this?
If there is any smarter way of being lazy I'd appreciate that too.
Thanks!
It's complicated, but it can be done, without leaving "expression-land":
// Get the initial property expression from the left
// side of the initial lambda. (someObjectThatMightBeNull.Property)
var propertyCall = (MemberExpression)expression.Body;
// Next, remove the property, by calling the Expression
// property from the MemberExpression (someObjectThatMightBeNull)
var initialObjectExpression = propertyCall.Expression;
// Next, create a null constant expression, which will
// be used to compare against the initialObjectExpression (null)
var nullExpression = Expression.Constant(null, initialObjectExpression.Type);
// Next, create an expression comparing the two:
// (someObjectThatMightBeNull == null)
var equalityCheck = Expression.Equal(initialObjectExpression, nullExpression);
// Next, create a lambda expression, so the equalityCheck
// can actually be called ( () => someObjectThatMightBeNull == null )
var newLambda = Expression.Lambda<Func<bool>>(equalityCheck, null);
// Compile the expression.
var function = newLambda.Compile();
// Run the compiled delegate.
var isNull = function();
That being said, as Andras Zoltan has so eloquently put in the comments: "Just because you can doesn't mean you should." Make sure you have a good reason to do this. If there's a better way to, then do that instead. Andras has a great workaround.
What you're talking about is called null-safe dereferencing - this SO specifically asks that question: C# if-null-then-null expression.
Expressions aren't really the answer (see below for clarification of my reasons for that statement). This extension method might be, though:
public static TResult? GetValueSafe<TInstance, TResult>(this TInstance instance,
Func<TInstance, TResult> accessor)
where TInstance : class
where TResult : struct
{
return instance != null ? (TResult?)accessor(instance) : (TResult?)null;
}
And now you can do:
MyObject o = null;
int? i = o.GetValueSafe(obj => obj.SomeIntProperty);
Assert.IsNull(i);
Obviously this is most useful when the property is a struct; you can reduce to any type and just use default(TResult) - but then you'd get 0 for ints, doubles etc:
public static TResult GetValueSafe<TInstance, TResult>(this TInstance instance,
Func<TInstance, TResult> accessor, TResult def = default(TResult))
where TInstance : class
{
return instance != null ? accessor(instance) : def;
}
This second version is more useful specifically because it works for any TResult. I've extended with an optional parameter to allow the caller to provide the default, e.g (using o from previous code):
int i = o.GetValueSafe(obj => obj.SomeIntProperty); //yields 0
i = o.GetValueSafe(obj => obj.SomeIntProperty, -1); //yields -1
//while this yields string.Empty instead of null
string s = o.GetValueSafe(obj => obj.SomeStringProperty, string.Empty);
Edit - in response to David's comment
David suggested my answer is wrong because it doesn't provide an expression-based solution, and that is what was asked for. My point is that any truly correct, and indeed responsible, answer on SO should always try to seek a simpler solution for the person asking the question if one exists. I believe it is widely accepted that over-complicated solutions to otherwise simple problems should be avoided in our day-to-day professional lives; and SO is only as popular as it is because it's community behaves in the same way.
David also took issue with my unjustified statement that 'they're not the solution' - so I'm going to expand upon that now and show why the expression-based solution is largely pointless, except in a rare edge-case that the OP doesn't actually ask for (which, incidentally, David's answer doesn't cover either).
The irony being that it makes this answer in itself perhaps unnecessarily complicated :) You can safely ignore from here down if you don't actually care why expressions aren't the best route
Whilst it is correct to say that you can solve this with expressions, for the examples laid out in the question there is simply no reason to use them - it's over-complicating what is ultimately quite a simple issue; and at runtime the overhead of compiling the expression (and subsequently throwing it away, unless you put caching in, which is going to be tricky to get right unless you emit something like call sites, like the DLR uses) is huge compared to the solution I present here.
Ultimately the motivation of any solution is to try and keep the work required by the caller to a minimum, but at the same time you also need to keep the work that is to be done by the expression analyzer to a minimum as well, otherwise the solution becomes almost unsolvable without a lot of work. To illustrate my point - let's look at the simplest we can achieve with a static method that takes an expression, given our object o:
var i = GetValueSafe(obj => obj.SomeIntProperty);
Uh-oh, that expression doesn't actually do anything - because it's not passing the o to it - the expression itself is useless to us, because we need the actual reference to o that could be null. So - the first of the solutions to this, naturally, is to explicitly pass the reference:
var i = GetValueSafe(o, obj => obj.SomeIntProperty);
(Note - could also be written as an extension method)
Thus the static method's job is to take the first parameter and pass it to the compiled expression when it invokes it. This also helps with identifying the type of the expression whose property is sought. It also, however, completely nullifies the reason to use an expression in the first place; since the method itself can immediately make the decision to access the property or not - since it has a reference to the object that could be null. Thus, in this case, it's easier, simpler and faster to simply pass a reference and accessor delegate (instead of an expression), as my extension method does.
As I mentioned, there is a way to get around having to pass the instance and that is to do one of the following:
var i = GetValueSafe(obj => o.SomeIntProperty);
Or
var i = GetValueSafe(() => o.SomeIntProperty);
We're discounting the extension method version - because with that we get a reference passed to the method, and as soon as we get a reference we can do away with expressions, as my last point proved.
Here we're relying on the caller to understand that they must include an expression that represents the actual instance (be it an in-scope property or field or local variable) in the body of the expression, on the left hand side of the member read, so that we can actually get a concrete value from it in order to do the null-check.
This is not a natural use of expression parameters, first of all, so I believe your callers could be confused. There's also another issue, which I think will be a killer if you intend to use this a lot - you cannot cache these expressions, because each time the instance, whose 'null-ness' you want to sidestep, is being baked into the expression that is passed. This means that you are always having to recompile the expression for every call; and that is going to be really slow. If you parameterise the instance in the expression you can then cache it - but then you end up with our first solution which required the instance to be passed; and again I've already shown there that we can then just use a delegate!
It is relatively easy - using the ExpressionVisitor class - to write something that can turn all property/field reads (and method calls for that matter) into 'safe' calls like you want. However, I cannot see any benefit to doing this unless you intend to do a safe read on something like this: a.b.c.d. But then the augmentation of value types to nullable versions of themselves is going to cause you a good few headaches in the expression-tree rewriting I can tell you; leaving a solution that hardly anyone will understand :)
I frequently face the problem to check whether an IEnumerable<T> is null before iterating over it through foreach or LINQ queries, then I often come into codes like this:
var myProjection = (myList ?? Enumerable.Empty<T>()).Select(x => x.Foo)...
Hence, I thought to add this extension-method to an Extensions class:
public static class MyExtensions
{
public static IEnumerable<T> AsEmptyIfNull<T>(this IEnumerable<T> source)
{
return source ?? Enumerable.Empty<T>();
}
}
A little issue comes immediately in my mind looking at this code, i.e., given the "instance-methods aspect" of extension-methods, it should be implemented as a mere static method, otherwise something like this would be perfectly legal:
IEnumerable<int> list = null;
list.AsEmptyIfNull();
Do you see any other drawback in using it ?
Can such extension leading to some kind of bad-trend in the developer(s), if massively used?
Bonus question:
Can you suggest a better name to it ? :)
(English is not my first language, then I'm not so good in naming...)
Thanks in advance.
Methods that return an IEnumerable<T> should return an empty one, instead of null. So you wouldn't need this.
See this question : Is it better to return null or empty collection?
Otherwise, your code seems ok.
It's generally a bad idea to return a null instead of an empty sequence if you can control it. This is self-explanatory if you consider that when someone is asked to produce a collection, returning null is not like saying "the collection is empty" but "there is no such collection at all".
If you own the methods returning the enumerables, then returning an empty IEnumerable (which can even be a special purpose readonly static object if it might be returned a lot) is the way to go, period.
If you are forced to use a bad-mannered library that has the habit of returning null in such cases, then this an extension method might be a solution, but again I wouldn't prefer it. It's probably better to wrap the bad-mannered methods in your own versions that do the coalescing where people won't see it. This way you get both the convenience of always having an enumerable instead of null and the correctness of not supporting the "return null" paradigm.
what is the point of allowing invocation of extension methods on null objects?
this is making me unnecessarily check for a null object in the extension method.
AFAIK,i can't understand this?
Please explain.
Extension methods are syntactic sugar of the C# language, they get compiled to normal static method calls in ILCode. A static method doesn't know anything about the parameters at compile time.
Simply put, why not?
You can sometimes skip the test if the first method you call within the extension would also throw the correct error.
You're essentially asking for the code to be different so that:
Uses which are reasonable on a null object, become disallowed.
Uses which don't need a null check (because it's implicit in something else) get the overhead of the needless check you want to happen automatically.
This seems a lot of an imposition on other uses just to save the one line of:
if(arg == null)throw new ArgumentNullException();
Extension methods are just syntactic sugar. In reality they are static methods on another class, so since you can write
IEnumerable<int> foo = null;
Enumerable.Count(foo);
You can also write
IEnumerable<int> foo = null;
foo.Count();
Sometimes, allowing the extension method to be called on a null object simplifies your code by allowing you to move the null check into the method instead at the call site. For example, you may have an extension method that returns a List<T>, but if called on a null object, returns an empty List<T>.
Extension methods are transformed to static method invocations so the code will still need to check for null arguments as there is no way to avoid the static method to be called normally without the extension method syntactic sugar.
Adding something like a check followed by a NullArgumentException could take execution time and the user may want to assert instead or use something else.
It would make the replacement more complex to explain or do automatically as the simple replacement of the extension method with the corresponding static method call will change the behavior of the code.
There are legitimate case where you want to allow null arguments (for exemple conversions from an object model to another where a null object of one type is converted to a null object of the second type)
Extension methods are just static methods:
List<int> x = null;
x.Count()
Is equivalent to:
List<int> x = null;
System.Linq.EnumerableExtensions.Count(x);
//EnumerableExtensions may not be the class, but you get the idea
Another beautiful example that wouldn't be possible otherwise:
public static bool IsNullOrEmpty(this string value)
{
return string.IsNullOrEmpty(value);
}
So you can use
string s = null;
if (s.IsNullOrEmpty()) // no null reference error!
...
Instead of
string s = null;
if (string.IsNullOrEmpty(s))
....
I'm trying to determine the equality of two predicates:
public T FirstOrDefault(Func<T, bool> predicate)
{
if (EntityCache.ContainsKey(predicate.GetHashCode()))
return EntityCache[predicate.GetHashCode()];
else
{
var entity = _objectSet.FirstOrDefault<T>(predicate);
EntityCache.Add(predicate.GetHashCode(), entity);
return entity;
}
}
The issue I'm having is the hash code of the predicate doesn't account for the values used inside it, and I'm not sure how to go about retrieving them.
If for instance the predicate passed to our method above is: (r => r.Id == id) how would I go about finding the value of 'id' inside my FirstOrDefault method?
You'll need to use Expression's. They contains func's, but they also contain the syntax tree and you can examine their 'source code' at runtime.
If I understand you correctly, you're trying to determine the value of a captured variable inside a delegate. I'm pretty sure there's no easy way to do this... perhaps if you used an expression tree instead of a delegate it would be simpler ?
Another option (probably much simpler) is keeping the values passed to the delegates alongside them in EntityCache
Also note that instead of
if (EntityCache.ContainsKey(predicate.GetHashCode()))
return EntityCache[predicate.GetHashCode()];
It would be better to use TryGetValue