Ability to track immutability?

I have a utility designed to transfer objects around our system. Since this is a multi-threaded environment, the utility makes a deep copy of each object it passes to prevent any thread safety problems. I am working on the transition of our system to the use of immutable objects to eliminate the need for this copy. I am wondering what is the best (fastest) way to detect that an object is immutable?

My first thought was to simply pick up the attribute that we applied to all of our immutable objects (MessageAttribute). As you can see from the performance profile below, it gets a pretty big hit (about 10 times to complete all my other checks).

enter image description here

, ? typeof(), , , , .

EDIT: , , , isDefined, else if, 10 , ( , ).

+4
4

Hash, , .

private static HashSet<Type> m_PassableTypes; // 


static SynthesisExtensions() { // 
    m_PassableTypes = new HashSet<Type>();
    foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) {
        foreach (Type type in assembly.GetTypes()) {
            if (type.IsValueType || type == typeof (string) || type.Module.Name == "FSharp.Core.dll" ||
                type.IsDefined(typeof (MessageAttribute), false)) {
                m_PassableTypes.Add(type);
            }
        }
    }
}

HashSet, .

    Type type = instance.GetType();

    if (m_PassableTypes.Contains(type)) {
        // cache the self-reference
        referenceCache.Add(instance, instance);
        // return the value itself
        return instance;
    }

!

+1

(, IImmutable) .

typeof(), .

typeof() - , .

+4

isDefined else, 10 , then. . 10 .

In addition, you can enter a cache for calculation. There are probably very few types you have ever checked, so the cache would be small.

+3
source

I would just cache the result, since type attributes will not change.

public class SomeHelperClass
{
    private static readonly ConcurrentDictionary<Type, bool> messageAttributesCache = new ConcurrentDictionary<Type, bool>();
    private static readonly Type messageAttributeType = typeof(MessageAttribute);

    public static bool IsMessageAttributeDefined(Type type)
    {
        bool isDefined = false;
        if (messageAttributesCache.TryGetValue(type, out isDefined))
        {
            return isDefined;
        }
        isDefined = type.IsDefined(messageAttributeType, false);
        return messageAttributesCache[type] = isDefined;
    }
}

Then use

bool isDefined = SomeHelperClass.IsMessageAttributeDefined(type);

You can make the solution general, I just give some idea, this is some kind of quick ugly code. However, it will be better.

+2
source

All Articles