两个不同的 类 具有相同的 AssemblyQualifiedName?
Two different classes with identical AssemblyQualifiedName?
在 MSTest 项目中,我为一些测试声明了一个内部 class。它在测试项目的命名空间中声明如下:
namespace Körningar.Test.Hjälpklasser
{
internal interface ITestkörningParams { int Heltal { get; } string Text { get; } }
internal class TestkörningParams : ITestkörningParams { public int Heltal { get; set; } public string Text { get; set; } }
// ...
}
在经过测试的方法中,我有一个 class parms
的实例,并遍历它的属性以记录它的值:
// Create parms of type körningsparametrarKlass.
object parms = paramhämtare.HämtaParametrar(args, körningsparametrarKlass);
// Log the property values of the parms object.
log.Info($"Körningsparametrar:\r\n"
+ string.Join("\r\n",
körningsparametrarKlass.GetProperties()
.Where(pi => pi.GetGetMethod() != null)
.Select(pi
=> $"{pi.Name} = {Convert.ToString(pi.GetGetMethod().Invoke(parms, null))}")
)
);
这行代码抛出 TargetException
消息,指出对象与目标类型不匹配。
paramhämtare.HämtaParametrar
创建的方法来自 NSubstitute 模拟对象,该对象执行以下操作:
paramhämtareMock.HämtaParametrar(new string[] { }, null).ReturnsForAnyArgs(new TestkörningParams());
我看不出 parms 对象如何可能是从 körningsparametrarKlass
中提取的 属性 getter 的错误类型,它与为 parms
对象。
检查 VS Watch 中的变量 windows 给出以下内容:
如您所见,parms
对象和 körningsparametrarKlass
类型的 AssemblyQualifiedName 相同,但实际类型对象不同(在转储中标记)。据我所知,类型对象应该使用 ==
进行比较,但我也使用 körningsparametrarKlass.Equals(parms.GetType())
进行了测试,结果相同。另请注意,Watch window 中的所有行实际上都是最新的,即使有些是灰色的 - 我在进行转储之前将它们全部刷新。
怎么会发生这种情况,我该如何解决?
我还应该提到,这似乎只有在我 运行 测试同一解决方案中的这个测试项目和另一个测试项目时才会发生。如果我 运行 只有有问题的测试,或者包含它的整个测试项目,没有例外。
[编辑]
我想到,当 Type 对象派生自测试程序集内的 AssemblyQualifiedName
时,可能会出现问题。此类型对象显然不同于测试程序集内部调用的 typeof(TheClass)
。只有当我运行同时测试这个测试程序集和另一个测试程序集时,才会出现这个问题。关于所讨论的类型,这些程序集之间不应该有任何名称甚至命名空间冲突。
我想我找到了问题的原因。
我有两个测试程序集,我们称它们为 Test1
和 Test2
,它们分别包含程序集 Ass1
和 Ass2
的测试。
Test1
引用了 Test2
。 Test2
包含一个名为 TheClass
.
的内部 class
在Ass2
中,一些代码使用程序集限定名来获取表示TheClass
.
的Type
对象
问题是此时TheClass
中有两个"versions":一个在Test2
中,一个被包含在Test1
中,因为该程序集对 Test2
.
的引用
所以,显然 Type
对象代表来自 Test1
的对象,而 Test2
中对 TheClass
的引用显然代表来自 Test2
的对象.
令我惊讶的是,测试框架实际上会在 运行 Test2
测试时加载 Test1
程序集。这应该发生吗?可以避免吗?
在 MSTest 项目中,我为一些测试声明了一个内部 class。它在测试项目的命名空间中声明如下:
namespace Körningar.Test.Hjälpklasser
{
internal interface ITestkörningParams { int Heltal { get; } string Text { get; } }
internal class TestkörningParams : ITestkörningParams { public int Heltal { get; set; } public string Text { get; set; } }
// ...
}
在经过测试的方法中,我有一个 class parms
的实例,并遍历它的属性以记录它的值:
// Create parms of type körningsparametrarKlass.
object parms = paramhämtare.HämtaParametrar(args, körningsparametrarKlass);
// Log the property values of the parms object.
log.Info($"Körningsparametrar:\r\n"
+ string.Join("\r\n",
körningsparametrarKlass.GetProperties()
.Where(pi => pi.GetGetMethod() != null)
.Select(pi
=> $"{pi.Name} = {Convert.ToString(pi.GetGetMethod().Invoke(parms, null))}")
)
);
这行代码抛出 TargetException
消息,指出对象与目标类型不匹配。
paramhämtare.HämtaParametrar
创建的方法来自 NSubstitute 模拟对象,该对象执行以下操作:
paramhämtareMock.HämtaParametrar(new string[] { }, null).ReturnsForAnyArgs(new TestkörningParams());
我看不出 parms 对象如何可能是从 körningsparametrarKlass
中提取的 属性 getter 的错误类型,它与为 parms
对象。
检查 VS Watch 中的变量 windows 给出以下内容:
如您所见,parms
对象和 körningsparametrarKlass
类型的 AssemblyQualifiedName 相同,但实际类型对象不同(在转储中标记)。据我所知,类型对象应该使用 ==
进行比较,但我也使用 körningsparametrarKlass.Equals(parms.GetType())
进行了测试,结果相同。另请注意,Watch window 中的所有行实际上都是最新的,即使有些是灰色的 - 我在进行转储之前将它们全部刷新。
怎么会发生这种情况,我该如何解决?
我还应该提到,这似乎只有在我 运行 测试同一解决方案中的这个测试项目和另一个测试项目时才会发生。如果我 运行 只有有问题的测试,或者包含它的整个测试项目,没有例外。
[编辑]
我想到,当 Type 对象派生自测试程序集内的 AssemblyQualifiedName
时,可能会出现问题。此类型对象显然不同于测试程序集内部调用的 typeof(TheClass)
。只有当我运行同时测试这个测试程序集和另一个测试程序集时,才会出现这个问题。关于所讨论的类型,这些程序集之间不应该有任何名称甚至命名空间冲突。
我想我找到了问题的原因。
我有两个测试程序集,我们称它们为 Test1
和 Test2
,它们分别包含程序集 Ass1
和 Ass2
的测试。
Test1
引用了 Test2
。 Test2
包含一个名为 TheClass
.
在Ass2
中,一些代码使用程序集限定名来获取表示TheClass
.
Type
对象
问题是此时TheClass
中有两个"versions":一个在Test2
中,一个被包含在Test1
中,因为该程序集对 Test2
.
所以,显然 Type
对象代表来自 Test1
的对象,而 Test2
中对 TheClass
的引用显然代表来自 Test2
的对象.
令我惊讶的是,测试框架实际上会在 运行 Test2
测试时加载 Test1
程序集。这应该发生吗?可以避免吗?