C# F#将对象扩展为字典

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

在工作缓慢的时候,我想把我编写的一个小DB访问框架从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;
}
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中存储值,以便传递它们(并最终填充适当的类,是的)