Possible Pitfalls of Using This (Extension Method Based) Shorthand

Possible pitfalls of using this (extension method based) shorthand

We independently came up with the exact same extension method name and implementation: Null-propagating extension method. So we don't think it's confusing or an abuse of extension methods.

I would write your "multiple levels" example with chaining as follows:

propertyValue1 = myObject.IfNotNull(o => o.ObjectProp).IfNotNull(p => p.StringProperty);

There's a now-closed bug on Microsoft Connect that proposed "?." as a new C# operator that would perform this null propagation. Mads Torgersen (from the C# language team) briefly explained why they won't implement it.

Evil use of Maybe monad and extension methods in C#?

It's interesting that so many people independently pick the name IfNotNull, for this in C# - it must be the most sensible name possible! :)

Earliest one I've found on SO: Possible pitfalls of using this (extension method based) shorthand

My one (in ignorance of the above): Pipe forwards in C#

Another more recent example: How to check for nulls in a deep lambda expression?

There are a couple of reasons why the IfNotNull extension method may be unpopular.

  1. Some people are adamant that an extension method should throw an exception if its this parameter is null. I disagree if the method name makes it clear.

  2. Extensions that apply too broadly will tend to clutter up the auto-completion menu. This can be avoided by proper use of namespaces so they don't annoy people who don't want them, however.

I've played around with the IEnumerable approach also, just as an experiment to see how many things I could twist to fit the Linq keywords, but I think the end result is less readable than either the IfNotNull chaining or the raw imperative code.

I've ended up with a simple self-contained Maybe class with one static method (not an extension method) and that works very nicely for me. But then, I work with a small team, and my next most senior colleague is interested in functional programming and lambdas and so on, so he isn't put off by it.

Null-safe dereferencing operator for older compilers?

There were quite a few attempts to do this before it became a language feature. It's a bit hard to find the references now, but you can get an idea how it can be done and why it's not that easy.

This snippet for example looks simple:

public static R NullSafe<T, R>(this T obj, Func<T, R> f) where T : class
{
return obj != null ? f(obj) : default(R);
}

You can use it almost like an operator:

deliveryCode = order.NullSafe(o => o.DeliveryCompany).NullSafe(dc => dc.FileArtworkCode);

But it doesn't work with value types. This older snippet uses EqualityComparer :

public static TOut NullSafe<TIn, TOut>(this TIn obj, Func<TIn, TOut> memberAction)
{
//Note we should not use obj != null because it can not test value types and also
//compiler has to lift the type to a nullable type for doing the comparision with null.
return (EqualityComparer<TIn>.Default.Equals(obj, default(TIn)))
? memberAction(obj)
: default(TOut);
}

It will take a bit of digging to find more complete examples. I remember trying methods similar to these way back when until I found a more complete one.

This SO answer to a similar question does away with chaining and allows one to write:

foo.PropagateNulls(x => x.ExtensionMethod().Property.Field.Method());

The implementation is a bit involved though, to say the least.

Having trouble finding out how to call this extension method on a DictionaryT,T

You've got some kind of build or scope error. This works perfectly. Are your extension methods in another assembly or namespace?

namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
Dictionary<string, string> dict = new Dictionary<string, string>();
dict.AttributesToString();
}
}

public static class Extensions
{
public static string AttributesToString<T, T1>(this Dictionary<T, T1> dict)
{
StringBuilder sb = new StringBuilder();

foreach (KeyValuePair<T, T1> kv in dict)
{
sb.Append(" " + kv.Key + "=\"" + kv.Value + "\"");
}

return sb.ToString();
}
}
}

Extension method or subclass to create a System.Drawing.Color based on another color and an alpha?

How about something like this:

public static class ColorExtensions
{
public static Color WithAlpha(this Color color, double opacity)
{
byte op = (byte)(opacity*255);
return Color.FromArgb(op, color.R, color.G, color.B);
}
}

The key is the this keyword in the first parameter. That (as well as being a static method in a static class) indicates to the compiler that this is an extension method.

Color transparentblue = Color.Blue.WithAlpha(0.5);

Further Reading

  • Extension Methods (C# Programming Guide)

Converting a null type to a list (error handling)

You can use a ternary operator:

 return new ADescription(file, name, othername==null?null:othername.ToList<string>());

Or create an extension method as described in the accepted response here Possible pitfalls of using this (extension method based) shorthand:

public static class IfNotNullExtensionMethod
{
public static U IfNotNull<T, U>(this T t, Func<T, U> fn)
{
return t != null ? fn(t) : default(U);
}
}

Your code would be:

return new ADescription(file, name, othername.IfNotNull(on => on.ToList());

Is there a way to implement and make use of a NOT null coalescing operator?

Mads Torgersen has publicly said that a null-propagating operator is under consideration for the next version of C# (but also emphasised that this doesn't mean it will be there). This would allow code like:

var value = someValue?.Method()?.AnotherMethod();

where the ?. returns null if the operand (on the left) is null, else will evaluate the right hand side. I suspect that would get you a lot of the way here, especially if combined with (say) extension methods; for example:

DateTime? dtStartDate = strStartDate?.MyParse();

where:

static DateTime MyParse(this string value) {
return DateTime.ParseExact(value, "dd.MM.yyyy",
System.Globalization.CultureInfo.InvariantCulture
);

However! You could do the same thing right now just using extension methods:

DateTime? dtStartDate = strStartDate.MyParse();

static DateTime? MyParse(this string value) {
if(value == null) return null;
return DateTime.ParseExact(value, "dd.MM.yyyy",
System.Globalization.CultureInfo.InvariantCulture
);

Advice on C# Expression Trees

Collecting PropertyInfo objects from Expression.Body seems similar to my solution to another question.



Related Topics



Leave a reply



Submit