如何将具有泛型约束的方法作为Func <t>传递?

时间:2016-06-20 22:52:37

标签: c# generics func type-constraints

在定义的抽象类中,我想创建两个静态方法,这些方法可以传递给定义的方法:

public static void AddType<T>(
    Func<XmlReader, T> ReaderFunc,
    Func<T, XmlWriter> WriterFunc ){
    /*Magic stuff happens here*/
}

这将是静态类:

public abstract class XmlModel : IXmlSerializable{

    static XmlModel( ){
        //Type Inference kicks in with other tests, but not this one T_T
        MyStaticClass.AddType( ReadModel, WriteModel );
    }

    private static T ReadModel<T>( XmlReader Reader ) where T : XmlModel, new( ){
        T Model = new T( );
        T.ReadXml( Reader );
        return T;
    }

    private static void WriteModel<T>( T Model, XmlWriter Writer ) where T : XmlModel{
        T.WriteXml( Writer );
    }

    public abstract void ReadXml( XmlReader Reader );
    public abstract void WriteXml( XmlWriter Writer );
}

我希望能够将ReadModelWriteModel传递给AddType方法的原因是因为该方法属于包含以下扩展方法的类,非常非常容易从Xml读取和写入值:

public static class ReaderWriters{
    private static Dictionary<Type, object>
        _dctTypeReader = new Dictionary<Type, object>( );
    private static Dictionary<Type, object>
        _dctTypeWriter = new Dictionary<Type, object>( );

    /// <summary>
    /// Add type reader/writer pair.
    /// </summary>
    /// <typeparam name="T">Type of object to be read and written.</typeparam>
    /// <param name="ReaderFunc">Func which returns value read.</param>
    /// <param name="WriterFunc">Func which writes value.</param>
    public static void AddType<T>(
        Func<XmlReader, T> ReaderFunc,
        Func<T, XmlWriter> WriterFunc ) {
        _dctTypeReader.Add( typeof( T ), ReaderFunc );
        _dctTypeWriter.Add( typeof( T ), WriterFunc );
    }

    public static T Read<T>( this XmlReader Reader ){
        if ( _dctTypeReader.ContainsKey( ( Key = typeof( T ) ) ) || ( Key =
             _dctTypeReader.Keys.FirstOrDefault( K => typeof( T ).BaseType == K ) ) != null ) {
            if ( Reader.ReadToFollowing( typeof( T ).Name ) )
                return ( _dctTypeReader[ Key ] as Func<XmlReader, T> )( Reader );
            else
                throw new XmlException( string.Format( "Failed to read into type {0}. Value was not found at expected location.", typeof( T ).Name ) );
        } else
            throw new KeyNotFoundException(
                string.Format( "Please define a method for reading objects of type {0}", typeof( T ).Name ) );
    }

    public static void Write<T>( this T toWrite, XmlWriter Writer ){
        /*Magic happens here*/
    }
}

通过这种方式,我可以继承XmlModel:

public class Foo : XmlModel{
    public override void ReadXml( XmlReader Reader ){
        /*Magic Happens Here*/
    }
    public override void WriteXml( XmlWriter Writer ){
        /*Magic Happens Here*/
    }
}

并且可以说Foo Model = SomeXmlReader.Read<Foo>( )Model.Write( SomeXmlWriter ) ...

我想在这里完成的是什么?我的意思是,我自己已经完全辞职了,必须手动完成继承我的XmlModel类的每个类,但是如果有某种方法可以这样做,我只需要定义它ONCE在抽象课中,这会让我很开心......

1 个答案:

答案 0 :(得分:2)

是的,你想要的是可行的。你遇到的大部分困难似乎来自过度使用静力学。一般情况下,除非你有充分的理由,否则不要使用静态。只需使您的类非静态并将通用实现放在类级别,就可以解决此问题。

在下面的示例代码中,我只是从XmlModel中删除了static,将泛型参数移到了类级别,并重命名了一些变量以遵循标准命名约定(局部变量和参数的小写名称)。除非我误解,否则这应该或多或少地做你正在寻找的东西。

public static class MyStaticClass
{
// Define other methods and classes here
    public static void AddType<T>(
        Func<XmlReader, T> ReaderFunc,
        Action<T, XmlWriter> WriterFunc ){
        /*Magic stuff happens here*/
    }
}


public abstract class XmlModel<T> where T : XmlModel<T>, new( )
{
    public XmlModel( ){
        //Type Inference kicks in with other tests, but not this one T_T
        MyStaticClass.AddType<T>( ReadModel, WriteModel );
    }

    private T ReadModel( XmlReader reader )  
    {
        T model = new T( );
        model.ReadXml( reader );
        return model;
    }

    private void WriteModel( T model, XmlWriter writer ) 
    {
        model.WriteXml( writer );
    }

    public abstract void ReadXml( XmlReader reader );
    public abstract void WriteXml( XmlWriter writer );
}
  • 列表项