3

私が使用しているライブラリの1つは、これをC#で定義しています。

public ushort GetParameterSet(string name, out ParameterSet parameterSet)

私はこれをF#から呼び出そうとしています:

let parameterSet = new ParameterSet();
let retVal = currentPanel.GetParameterSet(name, ref parameterSet);

ただし、parameterSetがC#メソッドで有効なデータを持つそのクラスのインスタンスに設定されていても、F#では変更されません。

ここで何が欠けていますか?

4

2 に答える 2

12

まず、コードがそのまま機能しない理由:refF#ではC#と同じ意味がありません。F#では、'a refタイプです。contentsそれも魔法ではありません-それは実際には次のように定義された単一のフィールドを持つ単なるレコードです:

type 'a ref = { mutable contents : 'a }

ローカル変数へのポインタまたは参照ではありません。したがって、これを書くとき:

let x = 0
let y = ref x

変数参照がありません。代わりに、タイプがの変数があり、の値は元の値(つまり、0)に初期化されています。あなたはそれを変えることができます:yxyint refcontentsx

y.contents <- 1

これにより、の値は変更されませんx。の値のみを変更しますcontents

F#は、の構文糖衣も提供します'a ref。具体的には、これ:

y.contents <- y.contents + 1

次のように短く書くことができます:

y := !y + 1

したがって:=、はに割り当てるための省略形contentsであり!、その値を読み取るための省略形です。

の詳細については、MSDNの参照セルrefを参照してください。

これで、F#には型に関連付けられたマジックキャストがあり、引数'a refを期待する外部関数にその型のインスタンスを渡すことができます( C#ではILにマップされます)。この場合、関数が引数の値を変更すると、それに応じてインスタンスのの値も変更されます。あなたの例では、の新しいインスタンスを作成し、それを変更する関数に渡してから破棄しました。あなたがすべきことはこれです:byrefrefoutbyrefcontentsrefref parameterSetref

let parameterSet = ref(new ParameterSet())
let retVal = currentPanel.GetParameterSet(name, parameterSet)
...
// use parameterSet.contents as needed

または、を使用let mutableして可変ローカル変数を宣言し、魔法の&演算子を使用して、次のように関数に直接渡すこともできbyrefます。

let mutable parameterSet = new ParameterSet()
let retVal = currentPanel.GetParameterSet(name, &parameterSet)
于 2009-08-13T19:33:55.093 に答える
4

試す

// let parameterSet = null;
let retval, parameterSet = currentPanel.GetParamterSet(name);

refメソッドが out パラメーターを予期する場合は、インスタンスをパラメーターとして渡すべきではありません(呼び出し時にoutキーワードが先行する割り当てられていない参照である必要があります)。

于 2009-08-13T19:11:03.323 に答える