Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does an implicit operator method in a nested class not compile?

This code gives an error:

public class A<T>
    {
        public class B<T1> : A<T1>
        {
            public static implicit operator bool(B<T1> b) => true;
        }
    }

But if I separate the classes, there is no error:


  public class A<T> {     }

  public class B<T> : A<T>
  {
       public static implicit operator bool(B<T> b) => true;
  }
like image 267
Evgeniy Terekhin Avatar asked Dec 22 '19 13:12

Evgeniy Terekhin


1 Answers

This is a very good question. I found that you can make the error go away by specifying A<T>.B<T1>:

public static implicit operator bool(A<T>.B<T1> b) => true;

So then I started to wonder why in this particular instance you need to qualify the inner class, because normally you don't.

Essentially, what you have written is an implicit conversion that can accept a type other than the enclosing type. Note that A<int>.B<string> and A<string>.B<string> are different classes.

Let's use a normal method, instead of an implicit conversion, to illustrate what's happening more clearly.

public class A<T>
{
    public class B<T1>
    {
        public static void F(B<T1> i) {}
    }
}

Note the absence of the inheritance clause. Bear with me for now. Here B<T1> actually means A<T>.B<T1>. This means that we can't do something like this:

A<int>.B<string>.F(new A<string>.B<string>()); // cannot convert type ...

So it would seem just writing B<T1> in the conversion would work. But when you introduce the inheritance clause...

public class A<T>
{
    public class B<T1>: A<T1>
    {
        public static void F(B<T1> i) {}
    }
}

A<int>.B<string>.F(new A<string>.B<string>()); // suddenly this compiles

This means that you can now pass something else other than A<T>.B<T1> to the implicit conversion, and that is not allowed.

like image 74
Sweeper Avatar answered Sep 22 '22 09:09

Sweeper