C#反思的理由

ljs*_*ljs 10 .net c# reflection

我想知道C#代码中反射的适当性.例如,我编写了一个函数,它迭代给定源对象的属性并创建指定类型的新实例,然后将具有相同名称的属性值从一个复制到另一个.我创建它来将数据从一个自动生成的LINQ对象复制到另一个,以避免LINQ中多个表的缺少继承.

但是,我不禁认为像这样的代码真的是"作弊",即不是使用提供的语言结构来实现给定的结束,它允许你绕过它们.

这种代码在多大程度上可以接受?有什么风险?这种方法的合法用途是什么?

Kei*_*ith 8

有时候使用反射可能有点像黑客,但很多时候它只是最奇妙的代码工具.

查看.Net属性网格 - 任何使用Visual Studio的人都会熟悉它.您可以将它指向任何对象,它将生成一个简单的属性编辑器.这使用反射,事实上VS的大多数工具箱都有.

查看单元测试 - 它们是通过反射加载的(至少在NUnit和MSTest中).

Reflection允许静态语言的动态风格行为.

它真正需要的一件事是鸭子打字--C#编译器已经支持这个:你可以foreach看到任何东西IEnumerable,无论它是否实现了接口.您可以在任何具有调用方法的类上使用C#3集合语法Add.

在需要动态样式行为的任何地方使用反射 - 例如,您有一组对象,并且您希望在每个对象上检查相同的属性.

动态类型的风险类似 - 编译时异常变为运行时异常.您的代码不是"安全",您必须做出相应的反应.

.Net反射代码非常快,但没有显式调用那么快.


Ome*_*ten 1

可能只是我,但我进入这个问题的方法是创建一个代码生成器 - 在运行时使用反射有点昂贵且无类型。创建根据最新代码生成的类并以强类型方式复制所有内容意味着您将在构建时捕获这些错误。

例如,生成的类可能如下所示:

static class AtoBCopier
{
    public static B Copy(A item)
    {
        return new B() { Prop1 = item.Prop1, Prop2 = item.Prop2 };
    }
}
Run Code Online (Sandbox Code Playgroud)

如果任一类没有属性或其类型发生更改,则代码无法编译。另外,时代也有了巨大的进步。