Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Net中没有虚拟方法调用的依赖项注入?_C#_.net_Dependency Injection_Inversion Of Control_Clr - Fatal编程技术网

C# Net中没有虚拟方法调用的依赖项注入?

C# Net中没有虚拟方法调用的依赖项注入?,c#,.net,dependency-injection,inversion-of-control,clr,C#,.net,Dependency Injection,Inversion Of Control,Clr,我一直在考虑是否可以在不产生虚拟方法调用成本的情况下应用DI模式(根据我做的实验,虚拟方法调用的速度可能比非虚拟调用慢4倍)。我的第一个想法是通过泛型进行依赖项注入: sealed class ComponentA<TComponentB, TComponentC> : IComponentA where TComponentB : IComponentB where TComponentC : IComponentC { ... } 密封类组件A:ICompon

我一直在考虑是否可以在不产生虚拟方法调用成本的情况下应用DI模式(根据我做的实验,虚拟方法调用的速度可能比非虚拟调用慢4倍)。我的第一个想法是通过泛型进行依赖项注入:

sealed class ComponentA<TComponentB, TComponentC> : IComponentA 
    where TComponentB : IComponentB
    where TComponentC : IComponentC
{ ... }
密封类组件A:IComponentA
其中TComponentB:IComponentB
其中TComponentC:IComponentC
{ ... }
不幸的是,即使TComponentB和TComponentC的具体实现被指定为泛型类型参数,并且所有类都声明为密封的,CLR仍然通过接口进行方法调用。让CLR执行非虚拟调用的唯一方法是将所有类更改为结构(实现接口)。但是,使用struct对DI来说并没有什么意义,这使得下面的问题更加无法解决

上述解决方案的第二个问题是它不能处理循环引用。我想不出任何方法,无论是通过C#代码还是通过构造表达式树来处理循环引用,因为这将需要无限递归泛型类型。(.Net确实支持泛型类型引用本身,但它似乎没有推广到这种情况。)因为只有结构可以导致CLR绕过接口,我认为这个问题根本无法解决,因为结构之间的循环引用可能会导致矛盾

我只能想到另外一个解决方案,而且它保证可以工作——在运行时从头开始发出所有类,可能是基于编译类作为模板。但这并不是一个理想的解决方案

谁有更好的主意


编辑:关于大多数评论,我想我应该说这是在“纯粹的智力好奇心”下提交的。我讨论了是否要问这个问题,因为我确实意识到我没有任何具体的案例需要这样做。我只是出于好玩的考虑,想知道以前是否有人遇到过这个问题。

虽然
callvirt
指令确实需要更长的时间,但通常会这样做,因为它在调用该方法之前为CLR提供了廉价的
null
检查。
callvirt
所用的时间不应明显长于
call
指令,特别是考虑到
null
检查

您是否发现,您可以通过创建类型(无论是
structs
还是使用静态方法的类)来显著提高应用程序的性能,从而保证C#编译器将发出
call
指令,而不是
callvirt
指令


我问这个问题的原因是,我想知道您是否要创建一个不可维护的代码库,它很脆弱,很难简单地用于解决可能存在或可能不存在的问题

在我看来,这是试图完全过度设计某些东西的典型例子。只是不要破坏你的设计,因为你可以节省10毫秒-如果它是那样的话


你是不是真的认为,由于
callvirt
的说明,你的应用程序最终会变得非常慢,以至于用户(你为其编写应用程序的人)会注意到任何差异?我对此非常怀疑。

这就解释了为什么你不能优化虚拟通话。

慢4倍??我觉得很难相信。我会在“过早优化”下提交这个文件…这是针对个人的,没有期限项目,所以我开始沉溺于过早的优化:“JTHG -过早优化可能会比仅仅期限更为痛苦。这看起来非常像C++中的策略模板。@ JTHG——我不能为安得烈说话,但可维护性、清晰度、可读性。可测试性通常比优化带来更多的好处。是的,使用结构确实将开销减少到几乎为零。我想我可能错误地解释了改进的原因。使用结构也减少了内存压力,但它们优雅地建模问题域的能力有限。这是一个很好的解释。谢谢