以下代码执行时没有错误并打印“ In some ”,这意味着语句
m[0].Invoke(o, args);
在对象some
上调用函数foo
,该函数是o
类的成员,并影响其公共变量i
。但是当我们取消注释代码的最后一行并尝试编译它时,它会产生错误。为什么?
using System;
using System.Reflection;
class foo
{
public int i;
public foo(int ii = 0)
{
i = ii;
}
public void some(int ii)
{
i = ii;
Console.WriteLine("In some ");
}
}
class main
{
static public void Main()
{
foo f = new foo();
object o = new foo();
Type t = typeof(foo);
object[] args = new object[1];
args[0] = 9;
MethodInfo[] m = t.GetMethods();
m[0].Invoke(o, args);
//Console.WriteLine(o.i);
}
}
答案 0 :(得分:4)
但是当我们取消注释代码的最后一行并尝试编译它时,它会产生错误。为什么?
因为您已将o
声明为System.Object
,就编译器而言,它没有定义变量i
。您需要将其强制转换为已知类型,或使用反射来检索此值。
例如:
// You can cast here, since you know the type
foo oAsFoo = o as foo;
Console.WriteLine(oAsFoo.i);
或者,使用反射来获取值:
FieldInfo field = t.GetField("i");
Console.WriteLine(field.GetValue(o));
答案 1 :(得分:2)
您需要强制o
foo
才能执行它。
Console.WriteLine(((foo)o).i)
C#是一种静态类型(类型安全)语言,只允许输入类型 安全操作,因为班级没有
public
成员i
object
因此编译器不允许这样做。
答案 2 :(得分:1)
o
属于object类型,可以保存任何类型的object
,但对象的实例无法访问assigned
类对象的属性。
对其各自的类进行类型转换,使公共成员可以像这样访问。
Console.WriteLine(((foo)o).i)