Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# method with byref parameter override

I'm trying to override a method with a byref parameter, the code below is an example

type Incrementor(z) =
    abstract member Increment : int byref * int byref -> unit
    default this.Increment(i : int byref,j : int byref) =
       i <- i + z

type Decrementor(z) =
    inherit Incrementor(z)
    override this.Increment(i : int byref,j : int byref) =
        base.Increment(ref i,ref j)

        i <- i - z

but the compiler give me this error:

A type instantiation involves a byref type. This is not permitted by the rules of Common IL.

I don't understand what is the problem

like image 732
Caelan Avatar asked Oct 21 '22 06:10

Caelan


1 Answers

I guess that this is related to section II.9.4 of the CLI spec (ECMA-335) which says that you cannot instantiate generic types with byref parameters.

But where is the generic type instantiation? Guessing again, I think this might be related to the signature of the abstract Increment method, which has int byref * int byref tuple in it. But, I wouldn't have expected a tuple to be created when calling a method.

The actual problem only seems to be triggered by the base.Increment(ref i, ref j) call, if you remove this then it compiles. It will also compile if you remove one of the byref params, e.g. abstract member Increment : int byref -> unit.

You could use explicit ref types instead, but it's not clear from your example what you are trying to do.

type Incrementor(z) =
    abstract member Increment : int ref * int ref -> unit
    default this.Increment(i: int ref, j: int ref) =
       i := !i + z

type Decrementor(z) =
    inherit Incrementor(z)
    override this.Increment(i: int ref, j: int ref) =
        base.Increment(i, j)
        i := !i - z
like image 110
Leaf Garland Avatar answered Oct 23 '22 00:10

Leaf Garland