I have two classes, GenericList
and SpecificList
, where SpecificList
inherits from GenericList
. GenericList
implements IEnumerable<GenericItem>
and SpecificList
implements IEnumerable<SpecificItem>
. SpecificItem
inherits from GenericItem
. I have to implement GetEnumerator
in both GenericList
and SpecificList
since they implement IEnumerable<T>
. In GenericList
, it's easy enough, I just return the enumerator for the underlying List<T>
:
public IEnumerator<GenericItem> GetEnumerator()
{
return genericItemsList.GetEnumerator();
}
However, in SpecificList
, it seems trickier. It seems risky to cast IEnumerator<GenericItem>
to IEnumerator<SpecificItem>
, and I don't know if that would even work. Instead, I did the following:
public new IEnumerator<SpecificItem> GetEnumerator()
{
IEnumerator<GenericItem> enumerator = base.GetEnumerator();
while (enumerator.MoveNext())
{
yield return (SpecificItem)enumerator.Current;
}
}
This compiles fine and a simple MSTest unit test calling SpecificList.GetEnumerator()
seems to show it works. However, ReSharper highlights base
in the above method with the following warning:
Access to GenericList.GetEnumerator through 'base' keywo开发者_C百科rd from anonymous method, lambda expression, query expression or iterator results in unverifiable code
Is this something I should worry about? Should I do something differently?
Edit: I'm using ReSharper 5.1 Full Edition Pre-Release Build 5.1.1715.35.
Also, I should take a break from running MSTest unit tests: I just hit Ctrl+R, Ctrl+T in Chrome to reload the page...
R# is correct that accessing the base
keyword inside an iterator / lambda in the 3.0 version of the C# compiler could result in unverifiable code. When it does or doesn't is a bit complex and I won't attempt to cover it here.
The easiest way to work around this is to wrap the call to base.GetEnumerator
in another non-static private method and reference that from your iterator.
private IEnumerator<GenericItem> GetBaseEnumerator() {
return base.GetEnumerator();
}
public new IEnumerator<SpecificItem> GetEnumerator()
{
IEnumerator<GenericItem> enumerator = GetBaseEnumerator();
while (enumerator.MoveNext())
{
yield return (SpecificItem)enumerator.Current;
}
}
I'm fairly certain this bug was fixed in the 4.0 version of the C# compiler.
It seems risky to cast
IEnumerator<GenericItem>
toIEnumerator<SpecificItem>
, and I don't know if that would even work.
Sure it would.
return base.Cast<SpecificItem>().GetEnumerator();
No more or less risky than your current implementation. In fact, I'm pretty sure it's more-or-less the same code under the hood.
精彩评论