C #: Is it possible to use the internal backend?

I have a generic class X<T> ; This class has a covariant part, which I want to have access covariantly. Therefore, I define it on the interface IX<out T> . However, I want this interface to be visible only to the class itself, because it also contains methods that must be private .

Ie, inside the class itself, I can raise to IX<T> and use it covariantly. For instance:.

 class X<T> : IX<T> { private interface IX<out T>{ // the private covariant interface void foo(); } // It grants access to the private method `foo` private T foo(){...} public T IX.foo(){ return foo(); } private static void someMethod(IX<T> x) { // Here I can use `x` covariantly } } 

Is it possible? I had never heard of private nested interfaces before, since a private interface usually does not make any difference. However, with the help of generics, such an interface becomes necessary to implement "covariance only for private access."

When I try to compile this, I get the following error:

 foo.cs(1,14): error CS0246: The type or namespace name `IX' could not be found. Are you missing an assembly reference? foo.cs(9,14): error CS0305: Using the generic type `X<T>.IX<S>' requires `1' type argument(s) 

Which is understandable in principle, for the internal type of the generic type, a type parameter for the external type is required. Is there a way to execute this code correctly?

+6
source share
2 answers

Edit: It looks like this is compiling on Roslyn / C # 6 tech preview , but not compiling on MS C # 5 compiler or monocompiling.


Yes, it’s like this, but note that in fact, the inner T not needed in many ways, and if you save it, it would be useful to call it TInner or something to avoid confusion, since T in X<T> technically different from X<>.IX<T> , although they will always actually be the same actual types:

 class X<T> : X<T>.IX<T> { private interface IX<out TInner> { // the private covariant interface void foo(); } // It grants access to the private method `foo` private T foo() { throw new NotImplementedException(); } void X<T>.IX<T>.foo() { throw new NotImplementedException(); } private static void someMethod(IX<T> x) { // Here I can use `x` covariantly } } 
+9
source

To compile and restrict the visibility of your interface only to your assembly, you can mark it as internal. The fact is that if it is declared as an internal type, it will not be considered by your class. This code should work:

 internal interface IX<out T> // the private covariant interface { T foo(); } class X<T> : IX<T> { // It grants access to the private method `foo` private T foo(){ return default(T); } T IX<T>.foo(){ return foo(); } private static void someMethod(IX<T> x) { // Here I can use `x` covariantly } } 

Thus, the interface is still private, but since it is not an internal type, it can be used in your class.

-1
source

Source: https://habr.com/ru/post/972446/


All Articles