开发者

Get variable name referring the object in C#

Is it possible to get the variable name using which the object was call开发者_如何学Pythoned in C#? Or is it possible to get all the variable which are referring a particular object?

EDIT: Just to clarify further even though this has been answered.

Consider the code sample given by Fredrik Mörk

User someUser = new User(); 
User anotherVariable = someUser; 

i.Is it possible to find someUser using the object reffered by anotherVariable.

ii. Is it possible to find get the name of the variable using which the object was called. That is something like someUser.getName() should give "someUser" as output.


No, there's no support for this. Of course, if you have a set of "candidate" variables (e.g. "find all the instance variables in this type, here's a bunch of objects of that type") then you can check whether any of them currently refer to a specific value. But otherwise, no.


I am not sure that I understand your question, but I interpret it this way:

User someUser = new User();
User anotherVariable = someUser;

Now you want to find someUser using the object referenced by anotherVariable (which is the user object originally assigned to someUser). If that is the question, the answer is no, that is not possible (AFAIK).


You can do this by using reflection to walk the object hierarchy and look for fields that reference the object you're looking for. Here's a function I use to accomplish this. You must provide a root object for its search.

This could probably be improved upon if you can look at the root stack frame and walk the local variables in there, but for my purposes, the app usually knows the rootmost object that it cares about.

// Spew all references to obj throughout the object hierarchy.
public static void FindReferences( object appRootObject, object obj )
{
    Stack<ReferencePath> stack = new Stack<ReferencePath>();
    FindReferences_R( stack, appRootObject, obj );
}

struct ReferencePath
{
    public ReferencePath( object parentObj, FieldInfo parentField )
    {
        m_ParentObject = parentObj;
        m_ParentField = parentField;
    }

    public object m_ParentObject;
    public FieldInfo m_ParentField;
}

static void PrintReferencePath( Stack< ReferencePath > stack )
{
    string s = "RootObject";
    foreach ( ReferencePath path in stack.ToArray().Reverse() )
    {
        s += "." + path.m_ParentField.Name;
    }
    System.Console.WriteLine( s );
}

static bool StackContainsParent( Stack< ReferencePath > stack, object obj )
{
    foreach ( ReferencePath path in stack )
    {
        if ( path.m_ParentObject == obj )
            return true;
    }

    return false;
}

static void FindReferences_R( Stack< ReferencePath > stack, object curParent, object obj )
{
    Type parentType = curParent.GetType();

    foreach ( MemberInfo memberInfo in parentType.GetMembers( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance ) )
    {
        FieldInfo fieldInfo = memberInfo as FieldInfo;
        if ( fieldInfo == null )
            continue;

        Type fieldType = fieldInfo.FieldType;
        if ( !fieldType.IsClass )
            continue;

        object value = fieldInfo.GetValue( curParent );
        if ( value == null )
            continue;

        stack.Push( new ReferencePath( curParent, fieldInfo ) );
        if ( value == obj )
        {
            PrintReferencePath( stack );
        }

        // Recurse, but don't recurse forever.
        if ( !StackContainsParent( stack, value ) )
        {
            FindReferences_R( stack, value, obj );
        }

        stack.Pop();
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜