2012-02-24 18 views
0

コードを使用してIList<T>FSharpList<T>に変換し、リストの値をXMLに書き込みます。私は自分のリストを作成する上記のコードを使用しFSharpList <string> to IList <string> to XML

public static class Interop 
{ 
    public static FSharpList<T> ToFSharpList<T>(this IList<T> input) 
    { 
     return CreateFSharpList(input, 0); 
    } 

    private static FSharpList<T> CreateFSharpList<T>(IList<T> input, int index) 
    { 
     if(index >= input.Count) 
     { 
      return FSharpList<T>.Empty; 
     } 
     else 
     { 
      return FSharpList<T>.Cons(input[index], CreateFSharpList(input, index + 1)); 
     } 
    } 
} 

var fsharp_distinct = distinctWords.ToFSharpList(); 
var distinct_without_stopwords = Module2.stopword(fsharp_distinct); 

foreach (string wd in distinct_without_stopwords) 
    colwordfreq.Root.Add(new XElement(wd)); 

Infactは、XMLは、あまりにも書かれてますが、単にループを終了する前にそれがSystem.NullReferenceExceptionを与えています。しかし、F#関数が同じコードを使用してTuple<string, int>を返したときに、Tuple値をXMLに書き込む際に問題はありませんでした。

EDIT:私は上記の質問で正しくありませんでした。ヌル点の例外が実際にこのコードから来た:

foreach (Tuple<string, int> pair in list2) 
    colwordfreq.Root.Element(pair.Item1).Add(new XElement("freq", pair.Item2)); 

をしかし、私は条件

if (colwordfreq.Root.Element(pair.Item1) != null) 

を追加したときには、その例外を与えるものではありません。

+0

例外は別のセクションのものだと思います。私はデバッグでそれを見つけました。 – codious

+0

@pad質問を編集しました。ヌル参照は、単語という単語を返すタプルから来ました。 – codious

+0

'pair.Item1'を' pair.Item1'に追加する前にルートノードに 'pair.Item1'を追加してみませんか?この方法では、安全で最初の文字列リストを作成する必要はありません。 – pad

答えて

2

あなたの例は少し不完全ですが、colwordfreq.Root.Element(pair.Item1)がいくつかの単語に対してnullを返す場合は、その要素を以前に追加しなかった可能性があります。たぶん、あなたのような何かを書くことで要素を追加する必要があります:あなたは、C#からF#コードを呼び出しているとき

別に
foreach (Tuple<string, int> pair in list2) 
    colwordfreq.Root.Add        // Add element to the root 
    (new XElement(pair.Item1,       // with the name of the word 
        new XElement("freq", pair.Item2))); // ... and the count 

、それはF# component design guidelinesをチェックアウトする価値があります。そこにある提案の1つ(強くお勧めします)は、C#のF#固有の型(FSharpListなど)の使用を避けることです。これらはF#用に設計されており、C#から正しく使用するのは難しいです。明示的にはF#を扱うことなく、

let rec stopword a = 
    match a with 
    |"the"::t |"this"::t -> stopword t 
    |h::t ->h::(stopword t) 
    |[] -> [] 

module Export = 
    let StopWord (inp:seq<_>) = 
    (inp |> List.ofSeq |> stopword) :> seq<_> 

が次にあなただけのC#からExport.StopWord(en)を呼び出すことができます:あなたはC#の中から使用する非常に簡単になりますIEnumerableを使用して機能を公開し、単純なF#のラッパー関数を追加することができ

リスト。

+0

F#ラッパーとコンプデザインのリンクをありがとう。私は同様の情報を探していました。 Infact、XML Imでは、既存のノードに子を追加しようとしています。既存のノードがない場合は、追加しません。だから、私はヌル状態を置くのです。 – codious