The "InternalsVisibleTo" attribute is key to any sort of "white-box" (the term of the decade, I guess) testing for .Net. It can be placed in any c# file with the "assembly" attribute on the front. Note that MS DOCs say that the assembly name must be qualified by the public key token, if it is signed. Sometimes that does not work and one must use the full public key in it's place. Access to internals is key to testing concurrent systems and in many other situations. See https://www.amazon.com/xUnit-Test-Patterns-Refactoring-Code/dp/0131495054. In this book, Meszaros describes a variety of coding styles that basically constitute a "Design For Test" approach to program development. At least that's the way I've used it over the years.
ADDED:
Sorry, I haven't been on here for a while. One approach is called the "testing subclass" approach by Meszaros. Again, one has to use "internalsvisableto" to access the base class's internals. This is a great solution, but it doesn't work for sealed classes. When I teach "Design For Test", I suggest that it's one of the things that are required to be "pre-engineered" into the base classes in order to provide testability. It has to become almost a cultural thing. Design a "base" base class that is unsealed. Call it UnsealedBaseClass or something uniformly recognizable. This is the class to be subclassed for testing. It is also subclassed to build the production sealed class, which often only differs in the constructors it exposes. I work in the nuclear industry and the testing requirements are taken VERY seriously. So, I have to think about these things all the time. By the way, leaving testing hooks in production code is not considered a problem in our field, as long as they are "internal" in a .Net implementation. The ramifications of NOT testing something can be quite profound.