使用代码将IList<T>
转换为FSharpList<T>
,然后将列表值写入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));
事实上,XML也是写的,但在退出循环之前,它给出了System.NullReferenceException
。但是当一个F#函数使用相同的代码返回Tuple<string, int>
时,我就没有问题将Tuple值写入XML。
编辑:我在上述问题中不正确。零点异常实际上来自此代码:
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 :(得分:2)
您的示例有点不完整,但如果某些单词colwordfreq.Root.Element(pair.Item1)
返回null
,则可能表示您之前未添加该元素。也许你需要通过编写类似的东西来添加元素:
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
除此之外,当您从C#调用F#代码时,值得查看F# component design guidelines。其中一个建议(我强烈建议遵循)是避免使用C#中的F#特定类型(如FSharpList
)。这些都是为F#设计的,很难从C#中正确使用。
您可以添加一个简单的F#包装函数,使用IEnumerable
公开该功能,这将更容易在C#中使用:
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)
而不明确处理F#列表。