使用包含协变类型的项目的访问器在单元测试项目中构建失败

发布于 2024-09-18 08:57:53 字数 856 浏览 9 评论 0原文

我向我们的项目添加了一个协变接口:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蘸点软妹酱 2024-09-25 08:57:53

这是 Visual Studio 2010 中的错误。已将其报告给 Microsoft Connect 但已关闭,显然不会修复。

根据 Bruce Taimana 的博客文章,私有访问器功能已停止,可能会在 Visual Studio 的未来版本中删除。列出的可能替代方案有:

  1. 使用 Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject 类帮助访问代码中的内部和私有 API。它可以在 Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll 程序集中找到。

  2. 创建一个反射框架,能够反射您的代码以访问内部或私有 API。

  3. 如果您尝试访问的代码是内部代码,您可以使用 InternalsVisibleToAttribute 访问您的 API,以便您的测试代码可以访问内部 API。

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:

  1. Use the Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject class to assist in accessing internal and private APIs in your code. This is found in the Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll assembly.

  2. Create a reflection framework that would be able to reflect off your code to access internal or private APIs.

  3. If the code you are trying to access is internal, you may be able to access your APIs using the InternalsVisibleToAttribute so your test code can have access to the internal APIs.

素年丶 2024-09-25 08:57:53

我正在努力解决这个错误,并且还收到一个错误:“BuildShadowTask”意外失败。当我尝试在这里解决该错误时,消除该错误的唯一方法是从泛型(即协变接口)中删除 out 关键字。

实际上,当 Resharper 建议我类型参数可以协变时,我收到了此错误:

private delegate TResult Action<TResult>(); 

更改为:

private delegate TResult Action<out TResult>();

遗憾的是,我不得不再次将其更改回来,并在评论中禁用 Resharper 警告:

// ReSharper disable once TypeParameterCanBeVariant 
private delegate TResult Action<TResult>();

因此,一种策略可以是搜索:

"<out"

在项目中并删除 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:

private delegate TResult Action<TResult>(); 

Changed to:

private delegate TResult Action<out TResult>();

Sadly, I had to change it back again and disabling the Resharper warning in a comment:

// ReSharper disable once TypeParameterCanBeVariant 
private delegate TResult Action<TResult>();

One strategy can therefore be to search for:

"<out"

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.

心在旅行 2024-09-25 08:57:53

如果您使用 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文