我在这个论坛上搜索过这些问题并找到了很好的资源。我自己编写了以下代码来理解反射的概念。
static void Main(String[] args)
{
MyClass1 mc1 = new MyClass1();
Type t = mc1.GetType();
MethodInfo mInfo = t.GetMethod("method1");
object[] o=new object[]{2};
Console.WriteLine(mInfo.Invoke(mc1, o));
NameSpace2.Class1 c1 = new NameSpace2.Class1();
Type t2 = c1.GetType();
MethodInfo[] mI2 = t2.GetMethods();
object[] o2 = new object[] {2,3};
foreach (MethodInfo m in mI2)
{
Console.WriteLine(m);
}
object x = Activator.CreateInstance(t);
Console.WriteLine(x.GetType());
Console.Read();
}
我理解通过反射,我将能够在运行时获取有关类型,公共方法,对象属性的信息,并且还能够创建该类型的对象。但我的观点是,除非我知道方法需要什么参数作为输入,否则我将无法实现任何方法,并且这些信息仅在运行时可用。那么,反思的重要性是什么,它只是关于对象的信息吗?
答案 0 :(得分:3)
如果您需要反思,那么您的需求无法在编译时解决,而是在运行时解决。
假设您正在制作一个需要模块化的酷应用程序,您可以让开发人员为您的应用程序编写插件。 您无法为可能创建的每个插件编译应用程序。然后,您需要加载,内省并使用反射调用插件的对象。
假设您正在为银行应用程序制作中间件,该中间件负责处理数据库连接并使用该数据执行某些业务逻辑。您可以为每个可用的数据库编写和编译中间件。或者您可以编写一次代码,并在运行时激活并使用正确的数据库驱动程序。
如果您希望动态获取WebService的WSDL,生成代理并在编译代理后立即使用Web服务并加载到内存中,该怎么办?想不出在编译时这样做的方法。
更好的是,如果使用CodeDOM生成代码,编译,加载已编译的程序集并使用刚刚编译的对象,该怎么办?
有一天你需要使用反射。我希望如此......
答案 1 :(得分:1)
除了 Adrian Salazar 的回答之外,我还有一些我去年面临的例子:
正如您所看到的,有很多例子证明反射确实很有用。在过去的8年里,我多次使用反射,我甚至无法计算使用次数。
答案 2 :(得分:0)
说出你的隐含问题。
但我的观点是,除非我知道方法需要哪些参数作为输入,否则我将无法实现任何方法,并且这些信息仅在运行时可用。
我们举一个简单的例子。我想在一个需要参数的类上实例化一个方法,我将成为辅导员(即我将创建该类并启动该方法,但我对此一无所知)。
public class Foo
{
public Foo() { }
public void FooMethod(string parm) { }
}
public class Facilitator
{
public void RaiseAction(string type, string action, params object[] parm)
{
var o = Activator.CreateInstance("MyAssembly", type);
var methodInfo = o.GetType().GetMethod(action);
if (methodInfo == null) { return; }
methodInfo.Invoke(o, parm);
}
}
现在,在上面的例子中,我只是将参数传递给我一无所知的对象上的方法。
现在,让我们来研究一下使用Reflection可能实现的其他一些事情。让我们想象一下,我需要找到一个private
成员 - 尽管通常是一个坏主意 - 如果有必要我可以做,我有时会调试 和 黑客攻击你有没有想过一个在运行时无法帮助你做出决定的旗帜?您在调试器中看到了该标志,但它隐藏在对象层次结构 和 中,它是private
来启动!更糟糕的是?微软表示,他们将在后续版本中以某种方式公开它,但你需要立即出门,你需要这个标志!或许你需要这种方法!
考虑这个例子(其中o
是某些对象,你需要私有的东西):
var propertyInfo = o.GetType().GetProperty("SomePublicProperty");
if (propertyInfo == null) { return; }
var myFirstPrivateMember = propertyInfo.PropertyType.GetField("_somePrivateField", BindingFlags.Instance | BindingFlags.NonPublic);
哦,我们刚刚得到了我们的第一个private
成员 - 而且还有一个领域!
反思是我的心脏,因为我已经构建了许多完全动态的应用程序,从数据库一直到用户体验。当您构建类似的应用程序时,您不了解任何内容 - 您没有配置它 - 但由于反射的灵活性,您可以Invoke
和Get
任何您想要或需要获得的内容完成的工作。
就像其他任何东西一样,这些是 非常 反射的简单例子,但希望你能够很好地理解反射的力量以及为什么它有用。在你的世界非常静止的大多数日常应用中,你可能永远都不会使用它,而是分支出来并获得更多动态,你需要它。