C# Attribute Checking is Inefficient
If an entity does not contain an attribute but we try to retrieve the attribute's value anyway, a NullReferenceException is thrown. Therefore, basic practice is to check that an entity contains an attribute before trying to retrieve the attribute's value. The following code snippet gets an account entity from a plugin's context then retrieves value for attribute address1_line1.
var account = (Entity)context.InputParameters["Target"];
if (account.Attributes.Contains("address1_line1"))
{
var line1 = account.GetAttributeValue<string>("address1_line1");
}
This is inefficient because .Contains() uses the same check as GetAttributeValue(), which internally refers to the actual entry location; the lookup functionality (finding the value of a key in a collection) is duplicated.
Use TryGetValue() instead
Last week I posted a set of useful extension methods to shorten our C# code, making it more readable and in some cases more efficient. Following on from this code, add a new extension method to the Extensions.cs class:
public static bool TryGetValue<T>(this AttributeCollection attributeCollection, string key, out T value)
{
object valueObj;
if (attributeCollection.TryGetValue(key, out valueObj))
{
try
{
value = (T)valueObj;
return true;
}
catch (InvalidCastException) { }
}
value = default(T);
return false;
}
This method tries to get an attribute's value and returns true if the attribute exists. Crucially, it also returns the value of the attribute if it exists, as an out parameter.
We can now rewrite our code to get the value for address 1 line 1 and only iterate through the attribute collection once:
var account = (Entity)context.InputParameters["Target"];
var line1 = string.Empty;
if (account.Attributes.TryGetValue("address1_line1", out line1))
{
// TODO: address1_line1 is contained within account.
}
It's important to remember that this is a micro-optimisation. We should still consider whether slightly more optimised code is actually worth it i.e. does it sacrifice code readability?
This post was inspired by a recent pull request from the .NET Roslyn compiler which is open-source and hosted here on GitHub.
Finally, for the curious, the performance difference between TryGetValue and Contains is discussed further here on StackOverflow.
This was originally posted here.

Like
Report
*This post is locked for comments