2016-03-03 58 views
0

這裏是我的代碼:發送各種類型列表在這同樣的方法

var res = PrepareData(null);    //Prepare Data Returns a Tuple if two list assigned below. 
List<Model.CameraSetting> lstCS = res.Item1; //List 1 
List<ValidObjectsCameraSetting> lstVOCS = res.Item2; // List 2 
if (isCSV) 
{ 
     DataTable dtCameraSettings = ImportExportReportHelper.ConvertListToDataTable(lstCS); 
     DataTable dtValidObjectCameraSetting = ImportExportReportHelper.ConvertListToDataTable(lstVOCS); 
} 

這裏是我的

public static DataTable ConvertListToDataTable(List<dynamic> list){ //Do Something }

方法。我怎樣才能在這裏發送任何類型的對象,並用它來做事情。 (我會做什麼配置)。

我只是想用這種方法發送各種類型的列表。

+2

也許你可以使它通用:'公共靜態數據表ConvertListToDataTable (名單列表)...' –

+0

你能包括一些更多關於你在'ConvertListToDataTable'方法中做什麼的細節?你打算如何使用反射或其他方式進行轉換? –

+0

是的,我希望如此。但不知道如何? –

回答

1

也許你可以把它generic

public static DataTable ConvertListToDataTable<T>(List<T> list) 
{ 
    Type listType = typeof(T); 
    if(listType == typeof(CameraSetting)) 
    { 
     //... 
    } 
    else if(listType == typeof(OtherThing)) 
    { 
     //... 
    } 
    else // if not everything is allowed 
     throw new NotSupportedException(listType.ToString() + " is not supported in ConvertListToDataTable"); 
} 
+0

這種方法違反了開放封閉原則:http://www.oodesign.com/open-close-principle.html。每次添加新類型時都必須對其進行修改。 –

+0

@JackA .:我只是想展示OP如何使用T的類型來區分它們,如果他需要的話。顯然這並不是必需的,因爲OP無論如何都在使用反射,並且所有類型都是允許的。然後我可以刪除整個方法體。但是我保留它,因爲它可以幫助未來的讀者。 –

+0

@JackA。 @TimSchmelter我已經有了反射的對象類型,然後用對象'propertyinfoes'創建了數據表列。然後,我使用列表對象值填充行,獲取每個對象類型(使用反射)並將屬性名稱與數據列名稱進行比較。由於我有100個這種類型的表,所以我決定做一個通用的方法,它將得到通用列表並給出一個數據表。有沒有更好的方法來做到這一點? –

0

您可以爲這兩個類例如ICameraSettings的交互界面,所以你不需要投的對象的方法內,然後改變你的列表,以

List<ICameraSettings> lstCS; 
List<ICameraSettings> lstVOCS; 

,或者您可以使用generics

public static DataTable ConvertListToDataTable<T>(List<T> list) where T:ICameraSettings 

如果你不需要與特定類型的工作,你可以使用ICollection的

public static DataTable ConvertListToDataTable(ICollection list) 

但是,如果你有不同的邏輯不同類型的方法中,可能需要使用parameter overloading

0

我會創建和接口,然後這兩個類實現它,這樣做,你可以做出該類型的接口列表。

編輯。而我打字很抱歉

1

使用非泛型和反射

如果你要使用的項目反映在列表中(和項目不是值類型)的人回答說,沒有特別的有理由使用通用列表類型。我還建議使用接口而不是特定的類型。例如:

public static DataTable ConvertListToDataTable(IEnumerable list){ 
    foreach (object item in list) 
    { 
     //Do Something 
    } 
} 

如果您需要在列表中的項目數,您可以使用ICollection代替IEnumerable

public static DataTable ConvertListToDataTable(ICollection list){ 
    if (list.Count > 0) 
    { 
     foreach (object item in list) 
     { 
      //Do Something 
     } 
    } 
} 

這兩個接口是通用List<>類來實現的,所以你可以將您的原始列表傳遞給不需要映射的函數。

使用泛型

有使用泛型的好處,特別是類型安全。使用泛型時,通常在用於類型參數的類型之間存在某種通用性。這是使用where類型約束強制執行的。

在這種特殊情況下,您的方法正在將集合中的項目轉換爲數據表格中的行。項目類型之間的通用性在於它們可以轉換爲數據行。這可以用一個接口來定義,像這樣:

public interface IDataRowConvertible 
{ 
} 

public class CameraSettings : IDataRowConvertible 
{ 
} 

public static DataTable ConvertListToDataTable<T>(IEnumerable<T> list) where T : IDataRowConvertible 
{ 
    // Do something 
} 

另一個要考慮的是這樣的:反射可能會非常棘手得到的權利。您最終可能會遇到您的基於反射的通用反射解決方案無法達到您想要的效果的情況。例如,假設您將某個屬性添加到您不希望包含在數據行中的某個類中。使用接口可以解決這兩個問題。

讓我們修改界面如下:

public interface IDataRowConvertible 
{ 
    void DefineColumns(DataColumnCollection columns); 
    void WriteToRow(DataRow row); 
} 

您現在正在負責制定所發生的數據表,以及轉換功能成爲真正通用的項目:

public static DataTable ConvertListToDataTable<T>(ICollection<T> list) where T: IDataRowConvertible 
{ 
    if (list.Count > 0) 
    { 
     var table = new DataTable(); 
     list.First().DefineColumns(table.Columns); 
     foreach (var item in list) 
     { 
      var row = table.NewRow(); 
      item.WriteToRow(row); 
      table.Rows.Add(row); 
     } 
     return table; 
    } 
    return null; 
} 

的最大的缺點是你所有的產品類都需要實現兩種接口方法。但是,您可以創建一個基於反射的實用工具,使他們更容易實現:

public void DefineColumns(DataColumnCollection columns) 
{ 
    ReflectionUtil.DefineColumns(this, columns); 
} 

public void WriteToRow(DataRow row) 
{ 
    ReflectionUtil.WriteToRow(this, row); 
}