[英]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.