簡體   English   中英

使用相同的方法發送各種類型的列表

[英]Send various types of list in this same method

這是我的代碼:

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 }

方法。 我該如何在此處發送任何類型的對象並進行處理。 (我要做的就是配置)。

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

也許您可以使其通用

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

使用非泛型和反射

如果要對列表中的項目使用反射(並且這些項目不是值類型),則沒有特殊的原因使用通用列表類型。 我還建議使用接口而不是特定類型。 例如:

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

您可以為兩個類(例如ICameraSettings創建一個相互接口,因此無需在方法內部ICameraSettings對象,然后將列表更改為

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

或者您可以使用泛型

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

如果您不需要使用特定類型,則可以使用ICollection

 public static DataTable ConvertListToDataTable(ICollection list)

但是,如果您對方法內部的不同類型使用不同的邏輯,則可能需要使用參數重載

我將創建並進行接口,然后兩個類都將其實現,從而可以列出該類型的接口。

編輯。 當我輸入抱歉時有人回答

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM