【问题标题】:Generic partial applied function in c#c#中的通用部分应用函数
【发布时间】:2013-12-29 11:02:39
【问题描述】:

在某些类组中有二进制序列化方法。该算法很简单:以某种顺序递归地写入所有嵌套对象中的所有原始类型字段。虽然类的结构可能会有所不同,但我需要一些功能来跟踪写入的数据。所以我最终想到了将字段名称和偏移量存储在一些xml 中的二进制流中。 这里是序列化的示例接口方法实现,必须在该组内的所有类中实现:

public XElement mySerialize(BinaryWriter bw)
{
    var x = new XElement("Class0",
        serializeAndProduceLog(id, "id", bw, bw.Write),
        serializeAndProduceLog(classFieldString, "classFieldString", bw, bw.Write),
        serializeAndProduceLog(classFieldLong, "classFieldLong", bw, bw.Write),
        classFieldObject0.mySerialize(bw),
        classFieldList.Select(o => o.mySerialize)
    );
    return x;
}

以下是实用方法:

    private XElement serializeAndProduceLog<T>(T field, string name, BinaryWriter bw, Action<T> f)
    {
        return new XElement(name, new XAttribute("type", field.GetType()), new Attribute("offset", writeField(field, bw, f)));
    }

    private long writeField<T>(T v, BinaryWriter bw, Action<T> f)
    {
        var p = bw.BaseStream.Position;
        f(v);
        return bw.BaseStream.Position - p;
    }

writeField 方法执行二进制写入操作,返回已写入的字节数。 我不想为每个BinaryWriter.Write 重载实例编写一堆重载包装器,所以通用参数f 可以解决问题。 现在,由于BinaryWriterBinaryWriter.Write 总是相同的,我的心血来潮是摆脱无聊的重复参数传递。我想介绍部分应用的功能,如

Func<int, string, XElement> serializeAndProduceLogInt = (field, name) => serializeAndProduceLog(field, name, bw, bw.Write);

但使用泛型参数而不是“int”。这在 C# 中可行吗?

【问题讨论】:

    标签: c# generics serialization functional-programming


    【解决方案1】:
    Func<T, string, XElement> SerializeAndProduceLogger<T>(BinaryWriter bw)
    {
        var method = typeof(BinaryWriter).GetMethod("Write", new Type[] { typeof(T) });
        if(method == null) throw new ArgumentException("No overload of write for type");
    
        Action<T> act = f => { method.Invoke(bw, new object[] { f }) };
        return (T field, string name) => serializeAndProduceLog(field, name, bw, act);
    }
    

    【讨论】:

    • 这段代码用反射看起来很复杂。我想找到在编译时推断类型的方法。但无论如何,谢谢。
    • @SergeyPrytkov - 我敢肯定,如果不使用反射,您将无法做到这一点。泛型不适用于重载,因为无法在方法调用站点对泛型参数进行专门化。
    猜你喜欢
    • 2011-05-02
    • 1970-01-01
    • 1970-01-01
    • 2012-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多