簡體   English   中英

如何將具有通用約束的方法作為Func傳遞 <T> ?

[英]How can I pass a method with generic constraints as a Func<T>?

我想在一個定義的抽象類中創建兩個可以傳遞給這樣定義的方法的靜態方法:

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讀取值和向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類的每個類都必須手動執行此操作,但是如果有某種方法可以只在抽象類中一次定義它,那會讓我很高興...

是的,您要做的是可行的。 您遇到的大多數困難似乎是由於過度使用了靜電。 通常,除非有充分的理由,否則不要使用靜態。 僅通過使您的類為非靜態並將通用實現置於類級別即可解決此問題。

在下面的示例代碼中,我只是從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 );
}
  • 項目清單

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM