如何处理私有成员访问器和集合?
我有一个像这样的类层次结构
public class A
{
protected class B
{
String Name { get; set; }
}
protected class C : KeyedCollection<String, B>
{
// ...
}
protected C Collection { get; }
// ...
public A Copy ()
{
// Creates a deep copy of this instance.
}
}
现在我想编写一个单元测试来比较 A 的两个实例在属性 KeyedCollection 中是否具有相同的项目 B。但是,我无法在 A 实例中执行 foreach 循环。我所尝试过的,
[TestClass]
public class TestClass
{
public void ATest()
{
A original = new A();
A copy = A.Copy();
// ...
A_Accessor originalAccessor = A_Accessor.AttachShadow(original);
A_Accessor copyAccessor = A_Accessor.AttachShadow(copy);
foreach(var originalItem in originalAccessor.Collection)
{
var copyItem = copyAccessor[originalItem.Name];
Assert.AreEqual(originalItem, copyItem);
}
}
}
此代码甚至无法编译,因为 C 类访问器没有实现 IEnumerable 接口(它没有实现 KeyedCollection 类中的任何接口)。有谁知道我该如何克服这个问题?
我收到的错误消息是
foreach 语句无法对“C”类型的变量进行操作,因为“A_Accessor.C”不包含“GetEnumerator”的公共定义
I have a class hierachy like this
public class A
{
protected class B
{
String Name { get; set; }
}
protected class C : KeyedCollection<String, B>
{
// ...
}
protected C Collection { get; }
// ...
public A Copy ()
{
// Creates a deep copy of this instance.
}
}
Now I'd like to write a unit test to compare if two instances of A have the same items B inside the property KeyedCollection. However, I'm not being able to perform a foreach loop into the A instances. What I had tried,
[TestClass]
public class TestClass
{
public void ATest()
{
A original = new A();
A copy = A.Copy();
// ...
A_Accessor originalAccessor = A_Accessor.AttachShadow(original);
A_Accessor copyAccessor = A_Accessor.AttachShadow(copy);
foreach(var originalItem in originalAccessor.Collection)
{
var copyItem = copyAccessor[originalItem.Name];
Assert.AreEqual(originalItem, copyItem);
}
}
}
This code doesn't even compile because the C class accessor doesn't implements the IEnumerable interface (it doesn't implement any interface from KeyedCollection class). Does anyone have an idea about how can I overcome this issue?
The error message I'm getting is
foreach statement cannot operate on variables of type 'C' because 'A_Accessor.C' does not contain a public definition for 'GetEnumerator'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我只是尝试编译您的示例:正如预期的那样,我收到错误
可访问性不一致:字段类型“AC”比字段“A.Collection”更难访问
。基本上这意味着您不能使用私有类型声明受保护的属性。因此,这不是您的测试代码的问题,而是要测试的代码的问题...
编辑
您可以使用
originalAccessor.Collection.Target
并将其转换为ICollection
。当然,在这种情况下,您只能枚举对象
,因此您必须再次强制转换每个项目:I just tried to compile your example: As expected I got an Error
Inconsistent accessibility: field type 'A.C' is less accessible than field 'A.Collection'
.Basically that means that you cannot declare a protected property using a private type. So it's not a problem with your test code but with the code to be tested ...
EDIT
You could use
originalAccessor.Collection.Target
and cast it toICollection
. Of course you can only enumerate overobject
s in this case, so you'll have to cast each item again:目前尚不清楚如何通过受保护的属性来公开私有类类型,但由于 C 派生自
KeyedCollection
它应该已经继承了 <代码>IEnumerable。目前尚不清楚您要做什么,但您仍然应该能够迭代集合......如果您甚至可以看到该属性。我怀疑您的代码由于其他原因而无法编译 - 因为
C
是根据私有成员类型声明的,尽管受到保护,并且因为您正在尝试访问C
> 首先来自不同的类(尽管它受到保护)。It's not clear how you're managing to expose a private class type via a protected property to start with, but as C derives from
KeyedCollection
it should already inherit the implementation ofIEnumerable<B>
.It's not really clear what you're trying to do, but you should still be able to iterate over the collection... if you can even see the property. I suspect your code doesn't compile for other reasons - because
C
is declared in terms of a private member type, despite being protected, and because you're trying to accessC
from a different class in the first place (despite it being protected).事实上,我找到的解决方案与马丁的建议非常相似:
感谢您的帮助!
卡洛斯.
Actually, the solution I found was very similiar to Martin's suggestion:
Thanks for all your assitance!
Carlos.
在我看来,您正在测试实现细节,而不是您的库用户的预期 API 级别。
It seems to me that you are testing an implementation detail, not the intended API level for users of your library.