-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Override all Read
methods in NullTextReader
and NullStreamReader
#64301
Conversation
Tagging subscribers to this area: @dotnet/area-system-io Issue DetailsThis is a fast-follow to #61898 (comment):
CC @adamsitnik
|
@@ -342,15 +342,41 @@ private sealed class NullTextReader : TextReader | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we even need NullTextReader? Seems like public static readonly TextReader Null = new NullTextReader();
could be changed to instead construct a NullStreamReader
. It's possible there's some reason I'm missing not to do that, but it'd be nice to avoid the duplication if possible. @adamsitnik, thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wondered this, too, as I refactored the classes to be almost identical; the only thing I can think of changing/breaking is code that (essentially) performs TextReader.Null is TextReader and not StreamReader
(or similar switch
/case
or if
/else
).
If setting TextReader.Null
to a NullStreamReader
(and deleting NullTextReader
) is desirable, let me know and I'm happy to make the change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The scenario provided by @bgrainger is valid, but I hope that nobody does that.
I've taken a look at how these two properties are typically used and I think that it's relatively safe to reduce the code duplication and remove NullTextReader
.
74f238e
to
9b2f3c1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your contribution @bgrainger ! PTAL at my comments.
src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TaskCache.cs
Outdated
Show resolved
Hide resolved
@@ -342,15 +342,41 @@ private sealed class NullTextReader : TextReader | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The scenario provided by @bgrainger is valid, but I hope that nobody does that.
I've taken a look at how these two properties are typically used and I think that it's relatively safe to reduce the code duplication and remove NullTextReader
.
@@ -19,7 +19,7 @@ namespace System.IO | |||
// There are methods on the Stream class for reading bytes. | |||
public abstract partial class TextReader : MarshalByRefObject, IDisposable | |||
{ | |||
public static readonly TextReader Null = new NullTextReader(); | |||
public static readonly TextReader Null = StreamReader.Null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall the code looks good, but for some reason the tests are failing on mono (the CI has not finished so I am not 100% sure that it's mono bug):
Discovering: System.IO.Tests (method display = ClassAndMethod, method display options = None)
Discovered: System.IO.Tests (found 694 of 700 test cases)
Starting: System.IO.Tests (parallel test collections = on, max threads = 6)
System.IO.Tests.NullTests.TestCanceledNullTextReaderAsync(input: null) [FAIL]
Assert.Throws() Failure
Expected: typeof(System.OperationCanceledException)
Actual: typeof(System.NullReferenceException): Object reference not set to an instance of an object
---- System.NullReferenceException : Object reference not set to an instance of an object
Stack Trace:
/_/src/libraries/System.IO/tests/Stream/Stream.NullTests.cs(184,0): at System.IO.Tests.NullTests.<>c__DisplayClass11_0.<<TestCanceledNullTextReaderAsync>b__0>d.MoveNext()
--- End of stack trace from previous location ---
----- Inner Stack Trace -----
/_/src/libraries/System.IO/tests/Stream/Stream.NullTests.cs(184,0): at System.IO.Tests.NullTests.<>c__DisplayClass11_0.<<TestCanceledNullTextReaderAsync>b__0>d.MoveNext()
--- End of stack trace from previous location ---
Assert.Throws() Failure
Is there any chance you could build it and try to repro locally? https://github.com/dotnet/runtime/blob/main/docs/workflow/building/mono/README.md
I have no idea why it fails only on Mono, but I guess it's caused by the fact that two out of three arugments provided by NullReaders
refer to the same object instance and somewhere in our stack (not in your PR) there is a bug.
runtime/src/libraries/System.IO/tests/Stream/Stream.NullTests.cs
Lines 197 to 203 in 57bfe47
public static IEnumerable<object[]> NullReaders | |
{ | |
get | |
{ | |
yield return new object[] { TextReader.Null }; | |
yield return new object[] { StreamReader.Null }; | |
yield return new object[] { StringReader.Null }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe it's actually 3 out of 3 now. StringReader.Null
always inherited from the base class, so it was the same object as TextReader.Null
. But now they all are the same object.
I could throw on a .Distinct()
to ensure that all the properties are read, but that only unique objects are tested, but I'm not sure if that would stop null
being passed as the input to the test method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just had a thought that perhaps this is a static field initialisation problem (only on mono)? If the base class static fields have to be initialised before the derived class, then TextReader.Null
would be set to null
, which would cause the test failure. The fix would be to make NullStreamReader
internal and simply construct a second instance in TextReader.Null
. (StreamReader.Null
technically wouldn't need to be a second instance, but could be = (StreamReader) TextReader.Null
but that feels unnecessarily brittle to me.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could throw on a
.Distinct()
That didn't fix the broken builds; I'll move ahead with the static field theory. (The Distinct()
is still useful to avoid unnecessary testing.)
Changing the static field initialisation has resolved the "Libraries Test Run release mono" build failures. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thank you @bgrainger !
This is a fast-follow to #61898 (comment):
CC @adamsitnik