答案 0 :(得分:14)
应该说.NET反射不是革命性的 - 概念已经在其他框架中出现了。
.NET中的反思有两个方面:
调查类型信息
如果没有某种反射/内省API,就很难执行序列化等操作。不是在运行时提供(通过检查属性/字段/等),而是经常需要代码生成,即明确知道如何序列化每个类型的代码。如果你想序列化没有双胞胎的东西,那就很乏味,也很痛苦。
同样,无处存储有关属性等的其他元数据,因此最终会有大量额外代码或外部配置文件。简单到能够将友好名称与属性(通过属性)相关联的东西是UI代码的巨大胜利。
<强>元编程强>
.NET反射还提供了一种在运行时创建类型(等)的机制,这对某些特定场景非常强大;替代方案是:
答案 1 :(得分:9)
我认为要了解.NET中反射的必要性,我们需要回到.NET之前。毕竟,像Java和C#这样的现代语言没有历史BF(在反射之前)。
C ++可能对C#和Java产生了最大的影响。但是C ++最初没有反射,我们编码没有它,我们设法得到了。偶尔我们有无效指针,并会使用强制转换强制它为我们想要的任何类型。这里的问题是演员阵容可能会因为可怕的后果而失败:
double CalculateSize(void* rectangle) {
return ((Rect*)rectangle)->getWidth() * ((Rect*)rectangle)->getHeight());
}
现在有很多争论,为什么你不应该首先将自己编码到这个问题中。但是当我们没有使用泛型时,问题与使用C#的.NET 1.1没有太大区别:
Hashtable shapes = new Hashtable();
....
double CalculateSize(object shape) {
return ((Rect)shape).Width * ((Rect)shape).Height;
}
但是,当C#示例失败时,它会使用异常而不是潜在的核心转储。
当反射被添加到C ++(称为运行时类型识别或RTTI)时,它受到了激烈的争论。在Stroustrup的“C ++的设计和演变”一书中,他列出了以下内容 反对RTTI的论点,有些人:
Declared the support unnecessary Declared the new style inherently evil ("against the spirit of C++") Deemed it too expensive Thought it too complicated and confusing Saw it as the beginning of an avalanche of new features
但它确实允许我们查询对象的类型或对象的特征。例如(使用C#)
Hashtable shapes = new Hashtable();
....
double CalculateSize(object shape) {
if(shape is Rect) {
return ((Rect)shape).Width * ((Rect)shape).Height;
}
else if(shape is Circle) {
return Math.Power(((Circle)shape).Radius, 2.0) * Math.PI;
}
}
当然,通过适当的规划,这个例子永远不需要发生。
因此,我需要它的真实世界情况包括:
所以,我会尽可能地认为,反思并没有能够做出以前无法做到的事情。但是,它确实使某些类型的问题更容易编码,读者更清楚,写入更短等等。
当然,这只是我的意见,我可能是错的。
答案 2 :(得分:1)
我曾经希望在文本文件中进行单元测试,可以由非技术用户以C ++格式进行修改:
MyObj Function args //textfile.txt
但我找不到一种方法来读取字符串,然后让代码创建一个由字符串表示的类型的对象实例,而不反映C ++不支持。
char *str; //read in some type from a text file say the string is "MyObj"
str *obj; //cast a pointer as type MyObj
obj = new str; //create a MyObj
另一种用途可能是拥有一个通用的复制功能,可以在不事先知道的情况下复制类的成员。
答案 3 :(得分:0)
当您在代码中使用[Obsolete]或[Serializable]等C#属性时,它会有很大帮助。像NUnit这样的框架在类上使用反射并包含了解哪些方法是测试,设置,拆卸等的方法。