2009-08-13 10 views
3
私はC#で定義にこれを使用しているライブラリの

一つ:私はF#のからこれを呼び出すためにしようとしているF#のオブジェクトをoutパラメータとして受け取るC#メソッドに渡すと機能しません。

public ushort GetParameterSet(string name, out ParameterSet parameterSet) 

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

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

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

答えて

4

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

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

を試してみてください。

+0

Wow nice ...なぜfsharpはrefキーワードを持っていて、それがうまくいかない場合(あなたのものはbtwです) – TimothyP

+0

'ref'と' out'の区別は純粋にC#の区別ではありません。 "outside" - 例えば、VBはそれを持っておらず、C# 'ref'と' out'の両方を 'ByRef'として扱います。また、初期化された変数を 'out'パラメータに渡すことは間違いありません。C#でも変数_must_が割り当て解除されている必要はありません。 –

+0

私はそれを知っていた*ことができる、私はあなたが*してはならないことを意味した。しかし、私はこれがC#であることを認識していませんでした。私はそれがCLRのものだと思っただけです。明確化のためにありがとう! –

11

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

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

それはローカル変数へのポインタまたは参照ではありません。あなたが書いたときにこのように、この:行う

let x = 0 
let y = ref x 

あなたはないは、変数yxを参照しています。代わりに、タイプ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#マップの両方のrefout)を見込んで外国関数にその型のインスタンスを渡すことができます'a refタイプに関連付けられた魔法のキャストを持っています。この場合、関数が引数の値を変更すると、refインスタンスのcontentsの値がそれに応じて変更されます。あなたの例では、ref parameterSetrefという新しいインスタンスを作成し、それを関数に渡してそれを変更し、それを破棄しました。あなたがやるべきことはこれです:また

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, &parameterSet) 
関連する問題