簡體   English   中英

動態設置 <T> 調用泛型方法時

[英]Dynamically setting the <T> when calling a generic method

我在嘗試對反序列化算法遞歸使用通用函數時遇到問題。 我正在按其值從XElement加載變量。 但是,如果它們不是原始類型,則必須遞歸地對該對象執行相同的操作。 但是,該對象與當前正在處理的對象類型不同。 例如,如果我有

 class someObject
 {
      otherObject obj = new otherObject();
 }

 class otherObject
 {
     int someInt = 123;
 }

解串器遞歸地進入另一個對象。 但是,問題是我必須動態更改通用方法的類型(即,我不知道在編譯時它將是哪種類型)。 算法如下:

public static T deserialize<T>(XNode element)
    where T : new()
{
    XElement currentNode = (XElement)element;

    FieldInfo[] fields = getFields<T>();

    T returnValue = new T();

    foreach (FieldInfo field in fields)
    {
        if (field.FieldType.IsPrimitive)
        {
            field.SetValue(returnValue, currentNode.Element(field.Name).Value);
        }
        else
        {
            //The issue is on the following line
            field.SetValue(returnValue, deserialize<???>(currentNode.Element(field.Name).Value));
        }
    }
}

我已經看到了很多有關如何動態創建類型列表和對象的文檔。 但是,我找不到任何有關在通用方法調用上動態切換類型的內容。

任何幫助是極大的贊賞! 讓我知道是否不清楚...

我將使泛型方法調用另一個私有的非泛型方法,該方法使用不同的方法來創建實例,而不是使用new T() 外部泛型方法對於方法的調用者來說將很方便,因此它們不必強制轉換響應。 在內部,您的代碼將更簡單。

請注意,.NET框架的反序列化方法至少都具有采用Type實例而不是通用類型參數( <T> )的重載。 這是由於要發現的原因-有時您將類型作為對象,然后就不能(明智地)調用泛型方法並傳遞該類型參數。

嘗試此操作,但是您必須使用屬性DataContract,DataMember標記該類

   static readonly XmlWriterSettings ws = new XmlWriterSettings()
    {
        OmitXmlDeclaration = true,
        Encoding = System.Text.Encoding.UTF8
    };


    static XElement ToXElement<T>(T obj)
    {
        StringBuilder sb = new StringBuilder();
        Type valorType = obj.GetType();
        using (var writer = XmlDictionaryWriter.Create(sb, ws))
        {
            DataContractSerializer s = new DataContractSerializer(typeof(T));
            s.WriteObject(writer, obj);
            writer.Flush();
            writer.Close();
        }
        return XElement.Parse(sb.ToString());
    }

    static T ToObj<T>(XElement node)
    {
        string xml = node.ToString(SaveOptions.DisableFormatting);      
        T respuesta = default(T);
        DataContractSerializer dcs = new DataContractSerializer(typeof(T));
        using (StringReader strReader = new StringReader(xml))
        {
            using (XmlReader xmlReader = new XmlTextReader(strReader))
            {
                respuesta = (T)dcs.ReadObject(xmlReader, false);
            }
        }
        return respuesta;
    }

測試:

    [DataContract]
    public class A
    {
        [DataMember]
        public int Prop { get; set; }
    }

        var node = ToXElement(12);
        int obj = ToObj<int>(node);


        var node2 = ToXElement(new A { Prop = 12 });
        A obj2 = ToObj<A>(node2);

暫無
暫無

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

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