简体   繁体   中英

Using reflection and transform C# to F# code

I'm trying to move some C# code to F# and I'm struggling to achive that in a specific method. Lack of how to Seq and Pipeline work properly when using reflection.

Here's in C#

        public static List<IList<object>> ConvertTTypeToData<T>(IEnumerable<T> exportList)
        {
            var type = typeof(T);
            var exportData = new List<IList<object>>();

            var properties = type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);

            foreach (var item in exportList.Where(x => x != null))
            {
                var data = properties.Select(property =>
                {
                    return property.GetValue(item).ToString();                    

                }).ToArray();
                exportData.Add(data);
            }

            return exportData;
        }

And unfortunately here is what I achieved at moment using F#

        member this.ConvertToGoogleRowsData(rows) = 
            let bindingFlags = BindingFlags.Public ||| BindingFlags.Instance

            let prop = typeof(T)

            let properties = prop.GetType().GetProperties(bindingFlags)

            let array = new ResizeArray<'T>()

            let test = rows |> Seq.toList
                             |> Seq.filter (fun x -> x != null )
                             |> Seq.iter (fun item ->
                                    array.Add(properties
                                              |> Seq.map (fun prop -> prop.GetValue(item).ToString())))
    abstract member ConvertToGoogleRowsData :
        rows: 'T seq
            -> obj seq seq

Could some good soul help me?

Advice and help much appreciated.

Thanks!

Even in the C# code, you could rewrite this to just use Select instead of constructing a remporary collection exportData and adding the results to the collection as you iterate over the input:

return exportList.Where(x => x != null).Select(item =>
  properties.Select(property => 
    property.GetValue(item).ToString()).ToArray()
)

In F#, you can do the same by using functions from the Seq module, instead of Select and Where extension methods. The equivalent:

let bindingFlags = BindingFlags.Public ||| BindingFlags.Instance
let typ = typeof<'T>
let properties = typ.GetProperties(bindingFlags) |> List.ofSeq  

rows 
|> Seq.filter (fun item -> item <> null)
|> Seq.map (fun item ->
  properties |> List.map (fun prop -> 
    prop.GetValue(item).ToString()) )

Depending on what data type exactly you want as a result, you may need to insert some Seq.toList or Seq.toArray calls, but this depends on what you want to do with the result. In the above, the result is seq<list<string>> , ie IEnumerable of immutable F# lists of strings.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM