0

I have a project with more than a dozen classes implementing .NET's Stream class (and more implementations likely to be added in the future). As I have recently discovered, asynchronous WriteAsync() and ReadAsync() operations are not safe on implementers if they rely on Stream.WriteAsync() or Stream.ReadAsync() if, as MSDN prescribes, implementor only provides implementation for synchronous Write() and Read() methods, and leaves asynchronous methods' functionality to be serviced by default implementation provided in Stream.WriteAsync() and Stream.ReadAsync(). (TL;DR: on some usages it can lead to a deadlock.)

Some derivations in my project intentionally provide their own override implementation of async variants, without call the base implementation at all. Others just rely on base implementation without having override methods. These two cases it seems I can determine at runtime with reflection, and act accordingly in the code for safe operation - use one way of doing things if it overrides; use another way if it doesn't.

However, there's a third, elusive case and that is if deriving class overrides the base's method, but in the body of the implementation eventually makes base.WriteAsync() or base.ReadAsync() calls to ultimately seek the service of the base implementation - and that potentially causing issue if I use the class in doing this as if it overrides, but really should use it as if it doesn't override.

So the question is: is it possible to inspect a class using reflection to determine if overriding method in its body makes a call to the base member that it overrides?

LB2
  • 4,802
  • 19
  • 35
  • Wouldn't it be better to catch these cases at compile time? E.f. by including a [Roslyn code analyzer](https://learn.microsoft.com/en-us/visualstudio/code-quality/roslyn-analyzers-overview?view=vs-2019) in your CI process? – Klaus Gütter May 15 '20 at 04:59
  • @KlausGütter, I haven't worked with Roslyn analyzers, but quick look tells me that it would allow compiler to throw error if a particular base method is called in override. But doing so is not necessarily an error in code - it simply means that at runtime I should select an appropriate method. So I think it's not quite what I'm looking for. [Code Generator](https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/) might be closer - though still a bit off (more complexity than it needs to be) – LB2 May 15 '20 at 05:11
  • Then maybe add an attribute to the class (verified by some compile-time checks) and evaluate this attribute at runtime? – Klaus Gütter May 15 '20 at 05:22
  • @KlausGütter, that relies on other developers on the project to just know to put that attribute, and is not really maintainable long-term (if refactor, remember to remove it?). I might as well just write consuming code by testing for "known bad types", but that too is obviously not good nor maintainable. – LB2 May 15 '20 at 05:46
  • There are plenty of questions on how to read method's IL (`GetMethodBody` is a good search term for something like [this](https://stackoverflow.com/questions/2693881/can-i-use-reflection-to-inspect-the-code-in-a-method)) and check if some conditions are true... if you really want to go that route. – Alexei Levenkov May 15 '20 at 06:39

0 Answers0