简体   繁体   中英

Passing a new instance of a Type through a Generic Method

I have a series of very similar methods:

    private static DocumentBody GetPdfBodyObject(int sectionId)
    {
        DocumentBody db = new DocumentBody();
        // Add some stuff to Db
        return db;
    }

    private static DocumentHeader GetPdfHeaderObject(int sectionId)
    {
        DocumentHeader dh = new DocumentHeader();
        // Add some stuff to DH - similar to above
        return dh;
    }

And so on...

As you can see the difference between these two examples is based around the Type that is being instantiated & returned.

So instantly I thought to use a Generic Method to reduce the code duplication... I just cant seem to figure out which way is the 'best practice' and can I get what I need without using reflection?

I haven't used Generic Methods much at all so any advice is welcome.

The best practice here would be to refactor static methods to factory methods or use builder pattern if it's a bigger object you're building (which it appears to be the case). The use of generic methods would be limited here to parameterless constructors - whenever the constructor would take parameters, you'd need to use the Activator, which is reflection and you generally do not want such code. Having said that: the two methods you gave construct objects using parameterless constructors, so you can refactor both to:

private static TT GetPdfObjectPart<TT>(int sectionId) where TT : class, new()
{
    TT dh = new TT();
    // Add some stuff to DH - similar to above
    return dh;
}

Also note, that as @dymanoid pointed out - in this case you can only use what is the part of the contract (the where clause) - so you'd need to implement some 'generic' interface to all constructed types - and you'd be limited to methods from the interface. It really looks like you're in classical situation to use the builder pattern.

As for me, interfaces are good:

private interface IDocumentPart
{
}

private class DocumentHeader : IDocumentPart
{
}

private class DocumentBody : IDocumentPart
{
}

private static T GetPdfPart<T>(int sectionId) where T : IDocumentPart, new()
{
       var doc = new T();
       return doc;
}

Of course, you can define some properties and methods common for all your classes in an interface.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM