簡體   English   中英

如何在C#中調用動態類型的Generic方法

[英]How to call a Generic method on a dynamic type in C#

我有以下代碼:

public static List<object[]> Serialise2D_Rec<T>(IEnumerable<T> data)
{
    int numElts = 0;
    foreach (var item in data)
        numElts++;

    Type t = typeof(T); // Get type pointer
    PropertyInfo[] propList = t.GetProperties();


    List<object[]> toret = new List<object[]>();

    for (long propID = 0; propID < propList.Count(); ++propID)
    {
        var proptype = propList[propID].PropertyType;
        if (proptype.IsPrimitive || proptype == typeof(Decimal) || proptype == typeof(String))
        {
            toret.Add(new object[numElts + 1]);
            toret[toret.Count - 1][0] = propList[propID].Name;
            int row = 1;
            foreach (T item in data)
            {
                toret[toret.Count - 1][row] = propList[propID].GetValue(item, null);
                row++;
            }
        }
        else
        {
            var lst = (IList)Activator.CreateInstance((typeof(List<>).MakeGenericType(proptype)));
            foreach (T item in data)
            {
                lst.Add(propList[propID].GetValue(item, null));
            }
            List<object[]> serialisedProp = Serialise2D_Rec(lst);

        }
    }
    return toret;

}

但是這條線將失敗:

List<object[]> serialisedProp = Serialise2D_Rec(lst);

有錯誤:

****: error CS0411: The type arguments for method '****.****.Serialise2D_Rec<T>(System.Collections.Generic.IEnumerable<T>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

如何在遞歸中指定類型,似乎動態泛型類型的語法不是那么簡單。

在您的情況下,我沒有看到有效的泛型用例。 泛型的使用假設您能夠在編譯時(或至少其祖先)靜態識別類型。 你為什么不接受非通用的IEnumerable 如果確實需要在data提供一些基本類型的項目,請將其作為參數提供:

public static List<object[]> Serialise2D_Rec(IEnumerable data, Type t)
{
    …
    for (…)
    {
        if (…)
        {
        }
        else
        {
            …
            List<object[]> serialisedProp = Serialise2D_Rec(lst, proptype);
        }
    }
}

附注:使用擴展方法data.Count()而不是foreach (var item in data) numElts++;

由於您的類型是動態的,因此在運行時之前您不會知道泛型參數的類型。 因此,您還必須將該函數視為動態函數,因為在運行時之前您不會知道函數的通用簽名的“類型”。

您必須使用反射動態調用泛型函數。 請參閱如何使用反射來調用泛型方法?

嘗試這個:

// Get The Method by reflection
    MethodInfo serializerInfo = typeof(Serializer).GetMethod("Serialise2D_Rec",
                        BindingFlags.Public | BindingFlags.Static); 

//Make a Generic instance of the type you want
    serializerInfo = serializerInfo.MakeGenericMethod(lst.GetType());

    List<object[]> serialisedProp = serializerInfo.Invoke(null, new object[] {lst});

而不是typeof()Serializer ,而是放置了包含func Serialise2D_Rec的類

在這種情況下,您似乎不能使用泛型。 該行失敗,因為lst是一個非泛型的IList ,它作為arguent傳遞給Serialise2D_Rec ,它需要一個IEnumerable<T>

我建議你改變你的方法不是通用的; 無論如何它都使用反射,它可能沒有太大的影響。

嘗試這個:

public static List<object[]> Serialise2D_Rec(IList data)
{
    int numElts = 0;
    foreach (var item in data)
        numElts++;

    if (data.Count == 0)
        throw new Exception("Cannot handle empty lists.");

    Type t = data[0].GetType(); // Get type pointer
    PropertyInfo[] propList = t.GetProperties();

    List<object[]> toret = new List<object[]>();

    for (long propID = 0; propID < propList.Count(); ++propID)
    {
        var proptype = propList[propID].PropertyType;
        if (proptype.IsPrimitive || proptype == typeof(Decimal) || proptype == typeof(String))
        {
            toret.Add(new object[numElts + 1]);
            toret[toret.Count - 1][0] = propList[propID].Name;
            int row = 1;
            foreach (object item in data)
            {
                toret[toret.Count - 1][row] = propList[propID].GetValue(item, null);
                row++;
            }
        }
        else
        {
            var lst = (IList)Activator.CreateInstance((typeof(List<>).MakeGenericType(proptype)));
            foreach (object item in data)
            {
                lst.Add(propList[propID].GetValue(item, null));
            }
            List<object[]> serialisedProp = Serialise2D_Rec(lst);

        }
    }

    return toret;
}

是的,那是因為lstobject類型。

您需要動態調用正確的通用類型Serialise2D_Rec<T>()

暫無
暫無

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

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