C# - 将变量类型传递给Generic方法

时间:2015-11-06 03:18:30

标签: c# generics npoi

我有使用NPOI的代码。
我正在尝试使用一个HSSFWorkbookXSSFWorkbook的对象,具体取决于excel文件的版本。

可以有一个Type并将其过去通用方法,然后转换为HSSFWorkbookXSSFWorkbook

如果它有效,我将以不同的方法使用GetWorkBook()

请参阅我对构造函数的评论。

public class ExcelReader
{    
    public ExcelReader(filePath)
    {
        var isXls = Path.GetExtension(_filePath) == ".xls";
        // Is the following possible or is there any work around to get it work.
        var type = isXls ? HSSFWorkbook : XSSFWorkbook; 
        var workbook = GetWorkBook<type>();
        // Other init...
    }

    public T GetWorkBook<T>()
    {        
        return (T)Workbook.GetSheetAt();
    }
}

3 个答案:

答案 0 :(得分:2)

泛型需要在编译时拥有Type。因此,通常情况下,您无法动态地将Type传递给泛型方法。

您可以使用此功能(使用reflection

public ExcelReader(filePath)
{
    var isXls = Path.GetExtension(_filePath) == ".xls";
    var type = isXls ? typeof(HSSFWorkbook) : typeof(XSSFWorkbook); //get the type for the method

    var getWorkBook = this.GetType().GetMethod("GetWorkBook"); //get the generic method dynamically
    var genericGetWorkBook = getWorkBook.MakeGenericMethod(type); //use the type

    var workBook = genericGetWorkBook.Invoke(this, null); //call the method
    //Other init...
}

在您的情况下,更简单的替代方法是不使用泛型

public ExcelReader(filePath)
{
    var isXls = Path.GetExtension(_filePath) == ".xls";
    var workBook = GetWorkBook(); //then cast or return object directly
    //Other init...
}

public object GetWorkBook()
{        
    return Workbook.GetSheetAt();
}

转换为所需类型

HSSFWorkbook hSSFWorkbook = null;
XSSFWorkbook xSSFWorkbook = null;
if (isXls)
    hSSFWorkbook = (HSSFWorkbook)workBook;
else
    xSSFWorkbook = (XSSFWorkbook)workBook;

答案 1 :(得分:0)

理想的方法是拥有HSSFWorkbook和XSSFWorkbook都继承的基本接口或类。

public IInterface GetWorkBook<T>()
{
     return Workbook.GetSheetAt();
}

并根据需要进行投射。

但如果您无法控制类,则可以使用动态

public dynamic GetWorkBook<T>()
{
     return Workbook.GetSheetAt();
}

但是在你走这条路之前,请先阅读动态。

答案 2 :(得分:0)

为什么不像这样简单地改变你的实现

    public ExcelReader(filePath)
{
    var isXls = Path.GetExtension(_filePath) == ".xls";

    if(typeof(isXls) == typeof(HSSFWorkbook))
          var workbook= GetWorkBook<HSSFWorkbook>();
    else if(typeof(isXls) == typeof(XSSFWorkbook))
          var workbook= GetWorkBook<XSSFWorkbook >();
    else{}
}

public T GetWorkBook<T>()
{  
    if(typeof(T) == typeof(HSSFWorkbook)     
     return (T)(object)(HSSFWorkbook)Workbook.GetSheetAt();
    return (T)(object)(XSSFWorkbook)Workbook.GetSheetAt();
}

根据您的类型使用条件语句。