2011-11-11 14 views
1

IModuleインターフェイスをエクスポートするモジュールがたくさんあります。だから、メインプログラムの中で、私は何の問題MEFの初期値なしでF#が変更可能

... 
let mutable modules = Seq.empty 
[<ImportMany>] 
member x.Modules 
    with get():IEnumerable<Lazy<IModule, IModuleData>> = modules 
    and set(a) = modules <- a 
... 

を持っていない。しかし、今私は戻ってそれらのモジュールへのインターフェイスを公開する必要があります。したがって、各モジュールは、単一のインターフェース

... 
let mutable parent:IParent = ? 
[<Import>] 
member x.Parent 
    with get():IParent = parent 
    and set(a) = parent <- a 
... 

がインポートされますので、私の問題は、私はそれのための初期値を持たないとき、私は私の可変「親」を作成行くのですかですか?また、これをAPIをコンポーネント部品に公開する適切な方法ですか?

+1

「null」を使用する場合は、let mutable parent:IParent = null? – pad

+0

私は "タイプ 'IParentは'適切な値として 'null'を持っていません"エラー – Jizugu

+3

'ヌル' = '未チェック.defaultof <_> ' – Daniel

答えて

1
let mutable parent = Unchecked.defaultof<IParent> 

このトリックを行う必要があります。

6

トリックを行う必要がありますUnchecked.defaultof<_>を使用して、それはあなたが行うには危険なものになるかもしれませんねF#の型システムを、回避していることを意味します - システムが誤ってnull値を参照解除(およびNullReferenceExceptionを取得)からあなたを防ぐためにしようとします。

F#で宣言されている型には、nullによって引き起こされる通常のエラーを排除しようとする、適切な値としてnullがありません。あなただけのあなたには、いくつかのC#でそれを使用する必要があるためIParentは、おそらく(null値を持つことができることを言いたい場合は

let mutable parent:option<IParent> = None 

[<Import>] 
member x.Parent 
    with get():IParent = 
     match parent with 
     | Some p -> p 
     | None -> failwith "TODO: Throw some reasonable exception here!" 
    and set(a) = parent <- Some(a) 

:クリーンF#のアプローチは、値が欠落しているという事実を表現するためのオプションの種類を使用することですとにかくF#の制限を無視するコード)では、タイプにnullを使用できる特別な属性を使用して型定義にマークを付けることができます。

[<AllowNullLiteral>] 
type IParent = 
    abstract DoStuff : unit -> unit 

次に、let mutable parent:IParent = nullと書くことができます。このアプローチの利点は、値null(ちょうどif parent <> null then ...を使用)が、Unchecked.defaultof<_>を使用したときにそれほど明白でないかどうかを簡単にチェックできることです。

0

Tomasが説明したことをフォローアップして、おそらくインポートをコンストラクタに直接入れるべきです。それはあなたのコードを少し慣れさせることができます。

関連する問題