我一直在考虑在C#代码中添加反射是否合适。例如,我编写了一个函数,该函数遍历给定源对象的属性,并创建指定类型的新实例,然后将相同名称的属性值从一个对象复制到另一个对象。我创建这个函数是为了将数据从一个自动生成的LINQ对象复制到另一个对象,以解决LINQ中缺少多个表的继承的问题。
然而,我仍认为像这样的代码实际上是“作弊”,即不使用提供的语言结构来实现特定目标,而是允许您规避它们。
这种代码的可接受程度是多少?有哪些风险?这种方法的合法用途是什么?
我一直在考虑在C#代码中添加反射是否合适。例如,我编写了一个函数,该函数遍历给定源对象的属性,并创建指定类型的新实例,然后将相同名称的属性值从一个对象复制到另一个对象。我创建这个函数是为了将数据从一个自动生成的LINQ对象复制到另一个对象,以解决LINQ中缺少多个表的继承的问题。
然而,我仍认为像这样的代码实际上是“作弊”,即不使用提供的语言结构来实现特定目标,而是允许您规避它们。
这种代码的可接受程度是多少?有哪些风险?这种方法的合法用途是什么?
foreach
任何看起来像IEnumerable
的东西,无论它是否实现了接口。您可以在任何具有名为Add
的方法的类上使用C#3集合语法。ExternalColor c = (ExternalColor)Enum.Parse(typeof(ExternalColor),
internalColor.ToString());
在底层,这也是反射,但由 .net 框架本身完成。现在,如果您决定将 InternalColor.Grey 重命名为 InternalColor.Gray,会发生什么?一切看起来都很好,构建也很好,甚至运行良好... 直到某一天,一些愚蠢的用户决定使用灰色...此时映射器将崩溃。
反射是一种非常有用的工具,没有它我无法生存。它可以使编程变得更加容易和快速。
例如,我在我的ORM层中使用反射来将属性赋值为来自表格的列值。如果没有反射,我就必须为每个表/类映射创建一个副本类。
至于上面提到的外部颜色异常。问题不在于Enum.Parse,而是程序员没有捕获正确的异常。由于解析了一个字符串,程序员应该始终假设该字符串可能包含不正确的值。
同样的问题也适用于.Net中的所有高级编程。"伴随着巨大的力量,必然会有巨大的责任"。使用反射可以给你带来很多力量。但请确保您知道如何正确地使用它。网上有数十个例子。
static class AtoBCopier
{
public static B Copy(A item)
{
return new B() { Prop1 = item.Prop1, Prop2 = item.Prop2 };
}
}
如果任何一个类都没有这些属性或它们的类型发生了变化,代码就无法编译。此外,时间方面也有巨大的改进。
反射使得实现插件架构变得非常容易,其中插件DLL可以在运行时自动加载(不需要在编译时显式链接)。
可以扫描这些DLL中实现/扩展相关接口/类的类。然后可以使用反射按需实例化这些类的实例。