使用包含协变类型的项目的访问器在单元测试项目中构建失败
我向我们的项目添加了一个协变接口:
interface IView
{
}
interface IPresenter<out TView> where TView : IView
{
TView View { get; }
}
我创建了一些类,实现了这些接口:
class TestView : IView
{
}
class TestPresenter : IPresenter<TestView>
{
public TestView View
{
get { return something; }
}
private void DoSomething()
{
}
}
我可以毫无问题地使用它:
IPresenter<IView> presenter = new TestPresenter();
所以一切看起来都是正确的,所以我假设我的协变用法是正确的。不幸的是,我们的单元测试项目包含来自同一项目中某些类型的私有访问器,例如协变接口,这会导致构建失败。
无法加载类型 'GenericInheritanceTest.IPresenter_Impl`1' 从装配 '通用继承测试_访问器, 版本=0.0.0.0,文化=中立, PublicKeyToken=null' 因为它 声明协变或逆变 类型参数且不是接口 或委托。
这里到底有什么问题呢?我的实施是否有失败?如何解决这个问题?不可能,一旦我们使用协变类型,我们就必须避免访问器???是否可以阻止为某些类型创建访问器来解决此问题?
I added a covariant interface to our project:
interface IView
{
}
interface IPresenter<out TView> where TView : IView
{
TView View { get; }
}
I created some classes, implementing these interfaces:
class TestView : IView
{
}
class TestPresenter : IPresenter<TestView>
{
public TestView View
{
get { return something; }
}
private void DoSomething()
{
}
}
And I can use this without problems:
IPresenter<IView> presenter = new TestPresenter();
So everything seems right, so I assume my covariance usage is correct. Unfortunately our unit test projects contain private accessors from some types located in the same project like the covariant interface, which causes a build failure.
Could not load type
'GenericInheritanceTest.IPresenter_Impl`1'
from assembly
'GenericInheritanceTest_Accessor,
Version=0.0.0.0, Culture=neutral,
PublicKeyToken=null' because it
declares a covariant or contravariant
type parameter and is not an interface
or delegate.
What exactly is the problem here? Is there a failure in my implementation, resp. how to fix this? Can not be, that we have to avoid accessors as soon as we use covariant types??? Is it possible to prevent creating accessors for certain types to solve this problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是 Visual Studio 2010 中的错误。已将其报告给 Microsoft Connect 但已关闭,显然不会修复。
根据 Bruce Taimana 的博客文章,私有访问器功能已停止,可能会在 Visual Studio 的未来版本中删除。列出的可能替代方案有:
This is a bug in Visual Studio 2010. It has been reported to Microsoft Connect but has been closed and will apparently not be fixed.
According to a blog entry by Bruce Taimana development of the private accessor feature has been stopped and may be removed in future versions of Visual Studio. Possible alternatives listed are:
我正在努力解决这个错误,并且还收到一个错误:“BuildShadowTask”意外失败。当我尝试在这里解决该错误时,消除该错误的唯一方法是从泛型(即协变接口)中删除 out 关键字。
实际上,当 Resharper 建议我类型参数可以协变时,我收到了此错误:
更改为:
遗憾的是,我不得不再次将其更改回来,并在评论中禁用 Resharper 警告:
因此,一种策略可以是搜索:
在项目中并删除 out 关键字,只是为了让它编译。
不是很优雅,但微软也不是很优雅,因为
这是五年前通过 Microsoft Connect 报道的,他们
选择关闭问题。问题出在单元测试项目中。这并没有帮助
从 Visual Studio 单元测试框架更改为 NUnit 测试框架。
I was struggling with this error and also got an error: The "BuildShadowTask" failed unexpectedly. The only way to get rid of the error when I tried resolving it here is removing the out keyword from generics, i.e. a covariant interface.
Actually I got this error when Resharper suggested to me that type parameter could be covariant:
Changed to:
Sadly, I had to change it back again and disabling the Resharper warning in a comment:
One strategy can therefore be to search for:
in a project and remove the out keyword, just to get it to compile.
Not very elegant, but not very elegant by Microsoft either, because
this was rapported five years ago through Microsoft Connect and they
have chosen to just close the problem. The problem is in Unit Test Projects. It does not help to
change from Visual Studio Unit Testing Framework to NUnit Testing Framework.
如果您使用 Unity Interception,并且您的参数标记为 out,则 Unity Interception 将导致此错误。这样做的原因是Interception必须能够读取参数列表。因此,与上面的情况类似,如果 Resharper 警告参数可以协变,则需要忽略此警告。
If you are using Unity Interception, and your parameter is labeled as out, Unity Interception will cause this error. The reason for this is that Interception must be able to read the parameter list. So Similar to the case above, if Resharper is warning that the parameter can be covariant, this warning needs to be ignored.