2016-12-26 22 views
5

の代わりにnullを返します。F#.net 4.6.1VS2015に開発しました。F#メソッドは、オプション

type CommonHelper = 
    static member SideEffectOnNull act x = if x = null then act(); x else x 
    static member SideEffectOnNotNull act x = if x <> null then act(); x else x 

...

static member GetPerformanceCounter (fname: CounterFullName) = 

     let getCounterInternal (counterFullName: CounterFullName) = 
      Log.Information("Getting counter: {category}\\{name}\\{instance} ", counterFullName.Category, counterFullName.Name, counterFullName.Instance) 
      let receivedCategory = PerformanceCounterCategory.GetCategories().FirstOrDefault(fun x -> String.Equals(x.CategoryName, counterFullName.Category.Category, StringComparison.InvariantCultureIgnoreCase)) 
      if receivedCategory = null then 
       Serilog.Log.Warning ("Category not found: {category}", counterFullName.Category); null 
      else 
       let receivedCounters = PerforrmanceCounterProxy.GetPerformanceCountersFromCategoryOrNull counterFullName.Instance receivedCategory 
       if receivedCounters = null then 
        Log.Warning ("Instance not found {name}(instance: {instance}) in category {category}", counterFullName.Name, counterFullName.Instance, counterFullName.Category); null 
       else 
        receivedCounters.FirstOrDefault(fun y -> String.Equals(y.CounterName, counterFullName.Name.Name, StringComparison.InvariantCultureIgnoreCase)) 
        |> CommonHelper.SideEffectOnNull (fun unit -> Log.Warning ("Name {name}(instance: {instance}) not found for category {category}", counterFullName.Name, counterFullName.Instance, counterFullName.Category)) 

     getCounterInternal fname 
     |> CommonHelper.SideEffectOnNull (fun unit ->Log.Warning("Getting counter failed: {category}\\{name}\\{instance}", fname.Category, fname.Name, fname.Instance)) 
     |> CommonHelper.SideEffectOnNotNull (fun unit ->Log.Information("Getting Counter secceed: {category}\\{name}\\{instance}", fname.Category, fname.Name, fname.Instance)) 
     |> (fun x -> if x = null then None else Option.Some(x)) 

しかし、私はnull代わりのoptionを受け、このメソッドを呼び出す:私はメソッドを持っています。 enter image description here 私は間違っていますか?

+2

私の推測 - 'visual studio 2015'に関連した問題。ビジネスロジックがうまくいくので、私は 'VS2015' UIが間違った情報を表示すると思います – burzhuy

+2

値型の場合は' default(T) '、参照型の場合は' null'を使って、その型のデフォルト値を表示しました。 – Asti

答えて

9

F#では、実行時にnullの定数を持つDUの1つのデータレス値を表すことができます。あなたがCompilationRepresentationFlags.UseNullAsTrueValueにそうするようにコンパイラに指示することができます

上記のコードで
[<CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue)>] 
type A = B | C of int 

printfn "%A" (obj.ReferenceEquals(B, null)) // will print "true" 

、DU値Bnullにコンパイルされます。これは時には最適化のために便利です。毎回インスタンスを割り当てるのではなく、定数を使用します。値が多用される場合に役立ちます。

したがって、Optionタイプでは、Noneのケースでこの同じテクニックが使用されます。そのため、Noneはデバッガにnullと表示されます。

デバッガには、この機能と他のF#機能を実装するための適切な拡張ポイントが用意されています。それまでは、デバッガはC#を話し、翻訳をやります。

+2

VS2015の前にデバッガが正常に動作しましたが、どうなりましたか? – scrwtp

+1

2015年以前には、デバッガが 'null'の代わりに' None'を表示していたと言いますか?あなたは絶対に確信していますか? –

+1

ちょうどチェックして、あなたが正しいです。私は精神的に、ヌルに 'Nones'を代用していたに違いありません。 – scrwtp

関連する問題