public List <KeyValuePair <string, string> > Morph(object args) { // Transform the args into a bag of key-value strings. var outputArgs = new List <KeyValuePair <string, string> >(); if (args != null) { if (!_noImplicitTransforms) { // given the type, fetch the implicit transforms for that type and put it in the implicitTransforms variable. Type argType = args.GetType(); TransformSpec implicitTransforms; // First check the one-element cache _firstImplicitTransformsEntry ImplicitTransformEntry cacheEntry = _firstImplicitTransformsEntry; if (cacheEntry != null && cacheEntry.Type == argType) { implicitTransforms = cacheEntry.Transforms; // Yeah we hit the cache. } else if (cacheEntry == null) { // _firstImplicitTransformsEntry is empty, we should fill it. // Note that it is OK that two threads may race and both call MakeImplicitTransforms on their own // (that is we don't expect exactly once initialization of _firstImplicitTransformsEntry) implicitTransforms = MakeImplicitTransforms(argType); Interlocked.CompareExchange(ref _firstImplicitTransformsEntry, new ImplicitTransformEntry() { Type = argType, Transforms = implicitTransforms }, null); } else { // This should only happen when you are wildcarding your events (reasonably rare). // In that case you will probably need many types // Note currently we don't limit the cache size, but it is limited by the number of // distinct types of objects passed to DiagnosticSource.Write. if (_implicitTransformsTable == null) { Interlocked.CompareExchange(ref _implicitTransformsTable, new ConcurrentDictionary <Type, TransformSpec>(1, 8), null); } implicitTransforms = _implicitTransformsTable.GetOrAdd(argType, type => MakeImplicitTransforms(type)); } // implicitTransformas now fetched from cache or constructed, use it to Fetch all the implicit fields. if (implicitTransforms != null) { for (TransformSpec serializableArg = implicitTransforms; serializableArg != null; serializableArg = serializableArg.Next) { outputArgs.Add(serializableArg.Morph(args)); } } } if (_explicitTransforms != null) { for (var explicitTransform = _explicitTransforms; explicitTransform != null; explicitTransform = explicitTransform.Next) { var keyValue = explicitTransform.Morph(args); if (keyValue.Value != null) { outputArgs.Add(keyValue); } } } } return(outputArgs); }