Today I encoutered problem connected with C#. I have to write an program which will pass some tests. Everything I implemented is working correctly, but there is one test which disallows using public fields, and it fails.
I have a generic class implementing IEnumerable, and the thing that causes problem is:
public IEnumerator<R> GetEnumerator()
{
foreach (R r in roomList)
yield return r;
}
If i put into this class "return null", test passes fine. I wonder what can be wrong? Here is a test report:
Result Message: Assert.Fail failed. Detected type "Exercise.Hotel`2+<GetEnumerator>d__0" with public filed(s) "Exercise.Hotel`2[R,SC] <>4__this, R <r>5__1, Enumerator <>7__wrap2", which is not allowed.
Here is also code of test. To be honest i am not very familiar with how it works. Of course it can be also caused by bad test.
var withPublicField = types.Where(t => !t.IsEnum)
.Where(t => t.GetFields(BindingFlags.Public | BindingFlags.Instance).Count() > 0)
.Where(t => !t.Name.StartsWith("<>c__DisplayClass"))
.ToDictionary(t => t.FullName, t => t.GetFields(BindingFlags.Public | BindingFlags.Instance));
Thanks for help. It's my first question so I hope that i did everything well :)
It's an odd test you are talking about.
The reason the iterator method (i.e. a method with yield return
in it) triggers the failure is that the C# compiler rewrites such methods to return an instance of a hidden class that implements the method as a state machine. It's that type that has the disallowed public fields in it.
Personally, it's my opinion that failure is a false positive. While I agree that public fields in general are an abomination, in this case you're dealing with hidden, compiler-generated code. This particular scenario should be fine.
Hopefully you can just suppress the failure in this case, with an explanation of "it's not my fault!" The alternative is to implement your own class that implements the IEnumerator<T>
type for the scenario, and which of course does not contain public fields.
EDIT: I notice looking at the test code that it already attempts to exclude compiler-generate code for captured variables (i.e. Name.StartsWith("<>c__DisplayClass")
). So perhaps the test author would add a similar exclusion for the compiler-generated <GetEnumerator>
types (or of course check for [CompilerGenerated]
per Lee's answer).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With