在工作缓慢的时候,我想将一个我用C#编写的小数据库访问框架转换为F# . 该框架广泛使用动态和ExpandoObjects . 特别是,这一点令我头疼:
public static List<dynamic> ToDynamic(this IDataReader reader)
{
dynamic result = new List<dynamic>();
while (reader.Read())
{
var item = new ExpandoObject();
var dc = item as IDictionary<String, object>;
for (int i = 0; i < reader.FieldCount; i++)
{
dc.Add(reader.GetName(i), DBNull.Value.Equals(reader[i]) ? null : reader[i]);
}
result.Add(item);
}
return result;
}
你怎么把它翻译成F#?这就是我能想到的:
let (~~) (x:obj) =
match x with
| :? 't as t -> t
| _ -> null
let rec mapper (reader : SqlDataReader) : list<'Value> =
match reader.Read() with
| false -> []
| true ->
let dc = new ExpandoObject()
let dictionary = ~~dc : Dictionary<string, obj>
[for i in [0 .. reader.FieldCount - 1] do
dictionary.Add(reader.GetName(i), reader.GetValue(i))] @ mapper reader
当然,除了字典在循环中出现空值 . ~~
应该用C#替换 as
运算符,但我想事情并不那么简单 . 这可能只是星期五的情况,但我真的看不清楚这一点 .
1 回答
由于动态没有语言支持,因此F#中涉及的内容稍微多一些 . (我建议阅读DynamicAttribute上的文档 . )这是一个翻译:
如果您只想动态访问
IDataReader
中的值,F#中更优雅的解决方案是重载动态运算符: