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

本文关键字:Generic 方法 变量 类型 C#- | 更新日期: 2023-09-27 18:20:42

我有使用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();
    }
}

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

泛型在编译时需要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...
}

在您的情况下,一个更简单的选择是不使用Generics

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;

理想的方法是有一个HSSFWorkbook和XSSFWorkbook都继承的基接口或类。然后进行

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

并根据需要铸造。

但如果你不能控制类,你可以使用动态

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

但在你走这条路之前,一定要读一读动态。

为什么不像这样简单地更改实现

    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();
}

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