1

I have a reference to class object that pointed to some class, say, XYZ as follow:

public class XYZ
{
     int x;
     int y;
     int z;
    XYZ()
    {
      x=0;
      y=1;
      z=2;
    }
};


object ObjRef;
ObjRef = new XYZ();

Now, I want to access member variable x, y and z through ObjRef. How can I achieve this?

Thanks in advance.

EDIT :

The class XYZ is inside client's DLL. I have loaded this class using

Assembly MyAssembly = Assembly.LoadFrom(AssemblyName)

Type XYZType = MyAssembly.GetType("XYZ");
Object ObjectRef = Activator.CreateInstance(XYZType);

So i don't have direct access to XYZ. I have Object reference that pointed to XYZ.

3
  • I believe you'd have to cast ObjRef to XYZ to access the members. Commented May 10, 2013 at 8:28
  • I'm a little confused - if you've loaded the class, why can you not instantiate the class, even if it's from a third party DLL? Commented May 10, 2013 at 8:35
  • Tim, because the project that contains Assembly.LoadFrom has no reference to the client DLL. Any types defined in it will not be available at compile-time. Commented May 10, 2013 at 8:48

8 Answers 8

4

Either use casting like other people have mentioned or if you don't know what to cast to at runtime, then use the System.Type.GetField method and use BindingFlags.NonPublic.

Sign up to request clarification or add additional context in comments.

Comments

3

Your classes using private variables. You should use the reflection to access private property as well private variables when you must create instance via outside assembly which you cannot access directly.

You can use reflector with BindingFlags.NonPublic and BindingFlags.Instance flags

FieldInfo[] fields = typeof(XYZ).GetFields(
                         BindingFlags.NonPublic | 
                         BindingFlags.Instance);

And access into private member following code statement below:

object objRef = new XYZ();
int x = (int)fields.Single(f => f.Name.Equals("x")).GetValue(objRef);

Comments

1

By casting it from object back to XYZ:

XYZ a = (XYZ) ObjRef;
int result = a.x;

That will cause an exception if ObjRef isn't an XYZ. You can also say:

XYZ a = ObjRef as XYZ;

which will return null if ObjRef isn't an XYZ.

2 Comments

I can't do that. class XYZ is in client's dll. I have load this dll using Assembly.LoadFrom(AssemblyName). so i have only objec reference to this instance. So i cant type cast by using (XYZ)
@someone_smiley: You really need to explain that in your question.
1

For reading the x-value:
((XYZ)ObjRef).x

Comments

1

If you do not have access to the original type, but you do happen to know both the names AND the types of the fields that you want to access, then you can use reflection as the following program demonstrates:

(Note: This assumes that the field is private as per your original post. If it is public, change BindingFlags.NonPublic to BindingFlags.Public)

using System;
using System.Reflection;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            new Program().Run();
        }

        void Run()
        {
            object obj = new XYZ();

            var xField = obj.GetType().GetField("x", BindingFlags.NonPublic | BindingFlags.Instance);

            int xValue = (int) xField.GetValue(obj);
            Console.WriteLine(xValue); // Prints 0

            xField.SetValue(obj, 42);  // Set private field value to 42
            xValue = (int)xField.GetValue(obj);
            Console.WriteLine(xValue); // Prints 42
        }
    }

    public class XYZ
    {
        int x;
        int y;
        int z;

        public XYZ()
        {
            x=0;
            y=1;
            z=2;
        }
    };
}

Comments

0

Just add public keyword to variable declaration. So it will be like this:

public int x;

8 Comments

public fields make hulk angry
I can't do that. class XYZ is in client's dll. I have load this dll using Assembly.LoadFrom(AssemblyName). so i have only objec reference to this instance
So object has a public variable named 'x'?
No. class XYZ has public x
You misunderstood my comment (or I misunderstood what you're trying to do). ObjRef is of type System.Object. I'm pretty sure that there is not a public x member in System.Object.
|
0

I would advise to use public properties to access those variables instead of making it public. Although it may look quite overkill in some case, this is, I think, a best practice. I also think in most recent versions of .NET framework (I'm still using 2.0...) it ca be performed quite simply with less code as soon as you have simple getter and setter.

I think this link can help

2 Comments

Automatically implemented properties are part of the language, not part of the framework - so you can use them when targeting .NET 2, so long as you're using a C# 3+ compiler. But I don't believe the question was really about that anyway...
Yeah now with the update of the question I realize my answer doesn't help at all. Thanks for the info about automatically implemented properties though, I will look back into it !
0

I think what you should really do is that you should define an interface in a separate DLL that is then referenced by your code as well as the client DLL. Class XYZ should implement that interface and you should utilize that interface to access X, Y & Z, as follows:

// this is in the DLL defining the interface
public interface IXyz
{
    int X { get; }

    int Y { get; }

    int Z { get; }
}

// this would be in the client DLL that you dynamically load in your code
public class Xyz : IXyz
{
    public int X { get; set; }

    public int Y { get; set; }

    public int Z { get; set; }
}

And then finally,

// this is your code where you create XYZ
IXyz xyz = new Xyz();

int x = xyz.X;

1 Comment

This is of course assuming if you have any control over the client DLL. If you do not, I suppose you could always create a wrapper class and enclose the reflection logic in there.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.