c# - Is there a way to pass an array of type parameters to a generic method? -



c# - Is there a way to pass an array of type parameters to a generic method? -

working on openxml, i've came across article: how to: merge 2 adjacent cells in spreadsheet document (open xml sdk).

there code sample there, wanted refactor. here part:

// insert mergecells object specified position. if (worksheet.elements<customsheetview>().count() > 0) { worksheet.insertafter(mergecells, worksheet.elements<customsheetview>().first()); } else if (worksheet.elements<dataconsolidate>().count() > 0) { worksheet.insertafter(mergecells, worksheet.elements<dataconsolidate>().first()); } else if (worksheet.elements<sortstate>().count() > 0) { worksheet.insertafter(mergecells, worksheet.elements<sortstate>().first()); } //...and 5 more

the best thing managed extension method:

public static bool insertelementafter<t>(this worksheet worksheet, openxmlelement element) t : openxmlelement { if (!worksheet.elements<t>().any()) homecoming false; else { worksheet.insertafter(element, worksheet.elements<t>().first()); homecoming true; } }

but usage looks much terrible original code:

if (!worksheet.insertelementafter<customsheetview>(mergecells)) if (!worksheet.insertelementafter<dataconsolidate>(mergecells)) if (!worksheet.insertelementafter<sortstate>(mergecells)) //...and 5 more

if somehow declare array (or something) of type parameters, able write this:

foreach (var t in typeparameterlist) { if (worksheet.insertelementafter<t>(mergecells)) break; }

but not know way this.

so options?

you create fluent api this. result allow code this:

worksheet.insertafter<customsheetview>(mergecells) .or<dataconsolidate>() .or<sortstate>();

there 2 advantages fluent api:

it expressive it works without reflection.

the implementation of api require class holds values , or() method:

public class chainedelementinserter { openxmlelement _element; worksheet _worksheet; bool _previousresult; // ctor initializes 3 fields goes here. public chainedelementinserter or<t>() t : openxmlelement { if (!_previousresult) _previousresult = _worksheet.insertelementafter<t>(_element); homecoming this; } }

the insertafter extension method starts chain , looks so:

public static chainedelementinserter insertafter<t>(this worksheet worksheet, openxmlelement element) t : openxmlelement { homecoming new chainedelementinserter( worksheet, element, worksheet.insertelementafter<t>(element)); }

c# generics

Comments

Popular posts from this blog

web services - java.lang.NoClassDefFoundError: Could not initialize class net.sf.cglib.proxy.Enhancer -

Accessing MATLAB's unicode strings from C -

javascript - mongodb won't find my schema method in nested container -