ConditionRacer
ConditionRacer

Reputation: 4498

How to generically build a reference graph for an object

I have a scenario where I need to recursively inspect all the references held by an object (regardless of whether it's public or private). The objects I need to inspect are very complicated and there are many different types so I'd prefer to write it generically if possible.

Something like this (just an example, the API is unimportant):

var myObject = new MyObject();
var graph = GetGraph(myObject);
foreach (var reference in graph.References)
{
    foreach (var subreference in reference.References)
    {
        // etc.
    }
}

It doesn't need to handle circular references. In fact, if it blows up on a circular reference that would be just fine since this is what I'm trying to detect. I'm guessing some clever reflection could do this, but I'm not very experienced with reflection. Any ideas?

Upvotes: 0

Views: 484

Answers (1)

Wim.van.Gool
Wim.van.Gool

Reputation: 1330

Just out of the top of my head, I'd implement it something like this. First, create a Node-class that represents one object of the object-graph like so:

internal sealed class Node
{
    private readonly object _instance;
    private readonly List<Node> _referencedInstances;

    private static readonly Dictionary<object, Node> _Nodes = new Dictionary<object, Node>();

    public static Node CreateGraph(object instance)
    {
        ...
    }

    private static IEnumerable<object> FindReferencesOf(object instance)
    {
        ...
    }
}

The Dictionary can be used to store all created nodes and check for circular references, if you want to. (It's like using a fly-weight pattern).

The CreateGraph(object instance) can be called recursively to build the whole graph, but you may want to avoid recursion if your object-graphs become large.

The FindReferences-method will have to use reflection to search for all FieldInfo-objects of the instances type that are:

  • public or non-public
  • of a reference type and not a value type (I presume)

Hope you can do something with this.

Upvotes: 1

Related Questions