我有一个包含几个成员的数据类
public interface IEquipmentHolder
{
ITypedServiceProvider<IGrabberChannel> VideoChannels { get; }
ITypedServiceProvider<IMicrophone> Microphones { get; }
ITypedServiceProvider<ISpeaker> Speakers { get; }
...
}和一个函数
void visitChilds<T>(ITypedServiceProvider<T> childsList) where T : INamedComponent
{
...
}在我代码的某个地方,我想为数据类的每个字段调用函数。所以我这么做了:
visitChilds(equipment.VideoChannels);
visitChilds(equipment.Microphones);
...但是,我可能会在数据类中添加一些新字段,并且不想忘记在那之后修复这些位置。
我的问题是:是否可以使用反射为类的每个数据成员调用泛型函数?如果不是,我们可以在c#代码中对新字段进行编译时检查吗?
发布于 2014-01-17 21:50:10
visitChilds()IEquipmentHolder只有一个属性ITypedServiceProvider<INamedComponent> Items { get; }反射比直接调用慢(也许你应该发出IL?)额外的代码可能不值得‘改进’,特别是如果很容易发现它没有访问的新集合。
还要考虑到,添加一组新的INamedComponents需要对IEquipmentHolder接口和所有实现进行重大更改。
发布于 2014-01-17 21:57:34
您可以使用Expression框架生成一个将为接口上的每个属性调用visitChilds的lambda。
您需要使用反射来生成表达式,但这将是一次性的。在那之后,你就有了一个动态编译的lambda,你可以调用它,这样会快很多。
我以前做过类似的事情,我将一个对象的实例转换成一个Dictionary<string,object>,其中每个键是属性的名称,值是属性的值。我们为每个我们想要转换的类型生成了一个lambda,并且它工作得非常好。
发布于 2014-01-17 22:29:53
如果ITypedServiceProvider是协变的,也就是这样声明的,
ITypedServiceProvider<out T>
{
...
}然后你就可以
IEquipmentHolder
{
IEnumerable<ITypedServiceProvider<INamedComponent>>
NamedComponents { get; }
}那么你就可以做到
void VisitChildren(IEquipmentHolder equipment)
{
foreach(var provider in equipment.NamedComponents)
{
provider.SomeMemberOfITypedServiceProvider();
}
}https://stackoverflow.com/questions/21187462
复制相似问题