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
Post a Comment