まず、コードが次のように機能しない理由:ref
は、C#と同じようにF#で同じ意味を持ちません。 F#では、'a ref
はタイプです。それはどちらか、魔法ではありません - それは本当に、次のように定義された単一のフィールドcontents
とちょうどレコードです:
type 'a ref = { mutable contents : 'a }
それはローカル変数へのポインタまたは参照ではありません。あなたが書いたときにこのように、この:行う
let x = 0
let y = ref x
あなたはないは、変数y
がx
を参照しています。代わりに、タイプint ref
の変数y
があり、contents
の値はx
(つまり0)の値に初期化されています。それを変更することができます:
y.contents <- 1
これは、x
の値を変更しません。 contents
F#も'a ref
の構文砂糖を提供しています。具体的には、この:
y.contents <- y.contents + 1
を書き込むことができるように、より短い:
y := !y + 1
したがって:=
がcontents
に割り当てるための速記であり、!
、その値を読み出すための省略表現です。
ref
の詳細については、MSDNのReference Cellsを参照してください。
今
F#が、あなたがbyref
引数(ILでbyref
のC#マップの両方のref
とout
)を見込んで外国関数にその型のインスタンスを渡すことができます'a ref
タイプに関連付けられた魔法のキャストを持っています。この場合、関数が引数の値を変更すると、ref
インスタンスのcontents
の値がそれに応じて変更されます。あなたの例では、ref parameterSet
はref
という新しいインスタンスを作成し、それを関数に渡してそれを変更し、それを破棄しました。あなたがやるべきことはこれです:また
let parameterSet = ref(new ParameterSet())
let retVal = currentPanel.GetParameterSet(name, parameterSet)
...
// use parameterSet.contents as needed
、あなたは変更可能なローカル変数を宣言した後、byref
として直接関数に渡すために魔法の&
演算子を使用するようにlet mutable
を使用することができます。
let mutable parameterSet = new ParameterSet()
let retVal = currentPanel.GetParameterSet(name, ¶meterSet)
Wow nice ...なぜfsharpはrefキーワードを持っていて、それがうまくいかない場合(あなたのものはbtwです) – TimothyP
'ref'と' out'の区別は純粋にC#の区別ではありません。 "outside" - 例えば、VBはそれを持っておらず、C# 'ref'と' out'の両方を 'ByRef'として扱います。また、初期化された変数を 'out'パラメータに渡すことは間違いありません。C#でも変数_must_が割り当て解除されている必要はありません。 –
私はそれを知っていた*ことができる、私はあなたが*してはならないことを意味した。しかし、私はこれがC#であることを認識していませんでした。私はそれがCLRのものだと思っただけです。明確化のためにありがとう! –