C# F#将对象扩展为字典
在工作缓慢的时候,我想把我编写的一个小DB访问框架从C#翻译成F#。该框架广泛使用动力学和ExpandoObjects。特别是,有一点让我头疼:C# F#将对象扩展为字典,c#,dynamic,f#,expandoobject,C#,Dynamic,F#,Expandoobject,在工作缓慢的时候,我想把我编写的一个小DB访问框架从C#翻译成F#。该框架广泛使用动力学和ExpandoObjects。特别是,有一点让我头疼: public static List<dynamic> ToDynamic(this IDataReader reader) { dynamic result = new List<dynamic>(); while (reader.Read()) { var item = new Ex
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;
}
publicstaticlist-ToDynamic(此IDataReader读取器)
{
动态结果=新列表();
while(reader.Read())
{
var item=新的ExpandoObject();
var dc=作为IDictionary的项目;
对于(int i=0;i
你怎么把它翻译成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
let(~~)(x:obj)=
将x与
| :? 't as t->t
|->null
let rec mapper(reader:SqlDataReader):list因为没有对动态的语言支持,这在F#中稍微多一些。(我建议您阅读上页的文档。)以下是一个翻译:
open System.Collections.Generic
开放系统.数据
开放系统。动态
open System.Runtime.CompilerServices
[]
让toDynamic(读取器:IDataReader):[]调整大小数组=
let results=ResizeArray()
让rec循环()=
如果是reader.Read(),则
设obj=ExpandoObject():>IDictionary
对于i=0到reader.FieldCount-1 do
Add(reader.GetName(i),如果reader.IsDBNull(i),那么null else reader.[i])
结果。添加(obj)
循环()
其他结果
循环()
如果您只想动态访问IDataReader
中的值,则F#中更优雅的解决方案是重载动态运算符:
let(?(读卡器:IDataReader)(名称:string)=
将读取器。[名称]与匹配
| :? DBNull->Unchecked.defaultof
|值->取消装箱值
//用法:读卡器?Id
简短回答的可能重复之处在于,向下投射并不像您想象的那样有效。谢谢。在F#仍然是个傻瓜,这帮了大忙!我不需要对读卡器进行动态访问,我希望在dynamics中存储值,以便传递它们(并最终填充适当的类,是的)