如何解决使用反射并将 C# 转换为 F# 代码
我正在尝试将一些 C# 代码移至 F#,但我正在努力以特定方法实现这一目标。在使用反射时,缺乏如何正确地进行 Seq 和 Pipeline 工作。
这里是 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;
}
不幸的是,这是我目前使用 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
有什么好心人能帮帮我吗?
非常感谢建议和帮助。
谢谢!
解决方法
即使在 C# 代码中,您也可以将其重写为仅使用 Select
,而不是构造一个临时集合 exportData
并在迭代输入时将结果添加到集合中:
return exportList.Where(x => x != null).Select(item =>
properties.Select(property =>
property.GetValue(item).ToString()).ToArray()
)
在 F# 中,您可以通过使用 Seq
模块中的函数而不是 Select
和 Where
扩展方法来执行相同的操作。等价物:
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()) )
根据您确切想要的数据类型,您可能需要插入一些 Seq.toList
或 Seq.toArray
调用,但这取决于您想要对结果做什么。在上面,结果是 seq<list<string>>
,即不可变 F# 字符串列表的 IEnumerable
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。