1

我有一个指向某个类的类对象的引用,比如 XYZ,如下所示:

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


object ObjRef;
ObjRef = new XYZ();

现在,我想通过ObjRef访问成员变量xyz。我怎样才能做到这一点?

提前致谢。

编辑 :

XYZ 类位于客户端的 DLL 中。我已经加载了这个类

Assembly MyAssembly = Assembly.LoadFrom(AssemblyName)

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

所以我无法直接访问 XYZ。我有指向 XYZ 的对象引用。

4

8 回答 8

4

要么像其他人提到的那样使用强制转换,或者如果您不知道在运行时要转换成什么,那么使用System.Type.GetField方法并使用BindingFlags.NonPublic

于 2013-05-10T08:29:44.420 回答
3

您的类使用私有变量。当您必须通过无法直接访问的外部程序集创建实例时,您应该使用反射来访问私有属性以及私有变量。

您可以将反射器与BindingFlags.NonPublicBindingFlags.Instance标志一起使用

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

并在下面的代码语句中访问私有成员:

object objRef = new XYZ();
int x = (int)fields.Single(f => f.Name.Equals("x")).GetValue(objRef);
于 2013-05-10T08:45:54.833 回答
1

通过将其从object后面投射到XYZ

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

如果ObjRef不是XYZ. 你也可以说:

XYZ a = ObjRef as XYZ;

null如果ObjRef不是XYZ. _

于 2013-05-10T08:28:37.243 回答
1

读取 x 值:
((XYZ)ObjRef).x

于 2013-05-10T08:28:50.110 回答
1

如果您无法访问原始类型,但您确实知道要访问的字段的名称和类型,那么您可以使用反射,如以下程序所示:

(注意:这假设该字段根据您的原始帖子是私有的。如果它是公开的,请更改BindingFlags.NonPublicBindingFlags.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;
        }
    };
}
于 2013-05-10T08:40:06.640 回答
0

我认为你真正应该做的是你应该在一个单独的 DLL 中定义一个接口,然后由你的代码和客户端 DLL 引用。XYZ 类应该实现该接口,您应该利用该接口访问 X、Y 和 Z,如下所示:

// 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; }
}

然后最后,

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

int x = xyz.X;
于 2013-05-10T08:44:14.040 回答
0

只需在变量声明中添加 public 关键字。所以它会是这样的:

public int x;
于 2013-05-10T08:28:11.497 回答
0

我建议使用公共属性来访问这些变量,而不是将其公开。尽管在某些情况下它可能看起来有点矫枉过正,但我​​认为这是一个最佳实践。我还认为,在 .NET 框架的最新版本(我仍在使用 2.0...)中,只要您有简单的 getter 和 setter,就可以用更少的代码非常简单地执行它。

我认为这个链接可以帮助

于 2013-05-10T08:32:54.250 回答