2015-11-06 104 views
0

我有使用NPOI的代碼。
我試圖讓一個對象將是一個HSSFWorkbookXSSFWorkbook取決於Excel文件的版本。C# - 將變量類型傳遞給泛型方法

有可能有一個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(); 
    } 
} 

回答

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; 
+0

我想我大部分時間都會使用Workbook上繼承NPOI提供的'HSSFWorkbook'和'XSSFWorkbook'的接口,並且如果我需要專門爲'XSSFWorkbook'的方法,我會將接口轉換爲'XSSFWorkbook'。順便說一句,謝謝! – janmvtrinidad

+0

在這種情況下,您的代碼看起來與替代方法非常相似。只需用你的界面替換對象。 –

+0

它需要投射才能使用HSSF或XSSF的方法。 – janmvtrinidad

0

理想的方法是讓HSSFWorkbook和XSSFWorkbook從中繼承的基本接口或類。然後有

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

並根據需要進行轉換。

但是,如果你沒有在類的控制,你可以使用動態

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

但是你走這條路之前做動態讀了。

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

只需使用基於你的類型的條件語句。