簡體   English   中英

如何在 C#.Net Core 中實現未知數組類型?

[英]How do I implement an unknown Array type in C# .Net Core?

我在下面有以下代碼,但還沒有弄清楚如何實現var results =部分,以便result[c] = valuesArray; 工作正常嗎?

    var result = Array.CreateInstance(typeof(Array), dt.Columns.Count);

            foreach (int c in Enumerable.Range(0, dt.Columns.Count))
            {
                // Create a list to hold values of the required type for the column
                var valuesArray = Array.CreateInstance(typeof(float), dt.Rows.Count);

                // Get the data to be written to the parquet stream
                for (int r = 0; r < dt.Rows.Count; r++)
                {
                    DataRow row = dt.Rows[r];

                    valuesArray.SetValue(row[c], r);
                }

                result[c] = valuesArray;

錯誤是:

Error: CS0021 = Cannot apply indexing with [] to an expression of type 'Array'

如何啟動Array使其正常工作?

看起來result.SetValue(valuesArray, c)會起作用。

您還可以使用

result.GetValue(c);

因此,如果您需要遍歷result ,您可以編寫一個與您已經編寫的類似的foreach

foreach (int c in Enumerable.Range(0, dt.Columns.Count))
{
   var x = result.GetValue(c);
}

正如您使用SetValue()方法為valuesArray設置值一樣,您可以對result執行相同的操作:

result.SetValue(valuesArray, c);

如果需要在迭代期間檢索值,可以使用result.GetValue(c)

foreach (int c in result)
{
    var retrievedResult = result.GetValue(c);
}

我嘗試過並正常工作的好方法是:

 var result = (dynamic)Array.CreateInstance(typeof(Array), columnLength);

示例代碼是:

int columnLength = 8;
var result = (dynamic)Array.CreateInstance(typeof(Array), columnLength);

foreach (int c in Enumerable.Range(0, columnLength)) {
    // Create a list to hold values of the required type for the column
    var valuesArray = Array.CreateInstance(typeof(float),columnLength);

    // Get the data to be written to the parquet stream
    for (int r = 0; r < columnLength; r++) {

        valuesArray.SetValue(r, r);
    }

    result[c] = valuesArray;
}

foreach (var arr in result)
    foreach (var value in arr)
        Console.Write($"{value}\t");
Console.ReadLine();

Output 是:

0       1       2       3       4       5       6       7       0       1       2       3       4       5       6
        7       0       1       2       3       4       5       6       7       0       1       2       3       4
        5       6       7       0       1       2       3       4       5       6       7       0       1       2
        3       4       5       6       7       0       1       2       3       4       5       6       7       0
        1       2       3       4       5       6       7

為此,您可以使用 generics。 您需要的唯一反射是每列執行一次內部 function 。

  • arrays的初始數組可以不用Array.CreateInstance
var method = this.GetType().GetMethod("GetArray");

var result = new Array[dt.Columns.Count];

for (int c = 0; c < dt.Columns.Count; c++)
{
    var generic = method.MakeGenericMethod(dt.Columns[c].DataType);
    result[c] = (Array)generic.Invoke(null, new[]{dt.Rows, c});
}
public static Array GetArray<T>(DataRowCollection rows, int c)
{
    var valuesArray = new T[rows.Count];
    for (int r = 0; r < rows.Count; r++)
    {
        DataRow row = rows[r];
        valuesArray[r] = (T)row[c];
    }
    return valuesArray;
}

在高性能場景中,您甚至可以將委托緩存到通用 function

static MethodInfo method = this.GetType().GetMethod("GetArray");

static Dictionary<Type, Func<DataRowCollection, int, Array>> funcs = new();
var result = new Array[dt.Columns.Count];

for (int c = 0; c < dt.Columns.Count; c++)
{
    if(!funcs.TryGetValue(dt.Columns[c].DataType, out var func)
    {
        func = funcs[dt.Columns[c].DataType] =
          (Func<DataRowCollection, int, Array>) method.MakeGenericMethod(dt.Columns[c].DataType)
             .CreateDelegate(typeof(Func<DataRowCollection, int, Array>));
    }
    result[c] = func(dt.Rows, c);
}

暫無
暫無

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

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