Pergunta

Usando um código para converter IList<T> para um FSharpList<T> em seguida, gravar a lista de valores de um 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));
        }
    }
}

Eu uso o código acima para fazer a minha própria lista

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));

De fato, o XML está escrito também, mas pouco antes de sair do laço dá um System.NullReferenceException.Mas quando um F# retornado de uma função Tuple<string, int> usando o mesmo código, eu não tinha problemas para escrever a Tupla de valores de um XML.

EDITAR: Eu não estava correta na questão acima.A ponto nulo exceção, na verdade, veio este código:

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

Mas quando eu adicionei a condição

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

Ele não dá a essa exceção.

Foi útil?

Solução

O seu exemplo é um pouco incompleto, mas se colwordfreq.Root.Element(pair.Item1) retorna null para algumas palavras, isso provavelmente significa que você não adicionar esse elemento anteriormente.Talvez você precisa adicionar elementos de escrever algo como:

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

De lado, quando você está chamando F# o código do C#, vale a pena conferir o F# componente diretrizes de design.Uma das sugestões de lá (o que eu recomendo fortemente seguir) é para evitar o uso de F# tipos específicos (como FSharpList) a partir do C#.Estas são realmente concebido para o F# e são difíceis de usar corretamente a partir do C#.

Você pode adicionar um simples F# função de wrapper que expõe a funcionalidade usando IEnumerable, que será muito mais fácil usar a partir do 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<_>

Em seguida, você pode apenas chamar Export.StopWord(en) C# sem explicitamente lidar com F# listas.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top