如何动态提供T ..类ObjectXMLSerializer <t>其中T:class </t>

时间:2010-09-16 13:18:52

标签: c# .net

好的,我想要使用的类声明为:

public static class ObjectXMLSerializer<T> where T : class

我有很多想要序列化的对象,但我不知道他们的“类”

object myclass = new MyNamespace.MyClass() as object;

如何执行以下操作...?

ObjectXMLSerializer< ? >.Save(myclass,"output.xml");

我不能这样做,因为预期的类型是“class”

ObjectXMLSerializer< myclass.GetType() >.Save(myclass,"output.xml");

这只是不起作用......

ObjectXMLSerializer< object >.Save(myclass,"output.xml");

任何想法都将不胜感激!

5 个答案:

答案 0 :(得分:7)

您正在尝试将泛型用于不适合的事物。

泛型旨在提供编译时安全性(并在编译时表达有关API的信息)。你不知道编译时涉及的类型,所以你遇到了问题。

选项:

  • 使用非通用API
  • 通过反射调用通用API
  • 重新设计代码,以便相关方法 在编译时知道类型(例如,使调用的方法 Save也是通用的)

答案 1 :(得分:1)

你可以在没有泛型的情况下尝试这个:

public static class ObjectXMLSerializer
{
    public static void Save(IXmlSerializable myObject, string fileName) 
    {
        // whatever
    }
}

虽然,根据您尝试做的事情,您可能最好只使用框架XmlSerializer而不是编写自己的框架。

答案 2 :(得分:0)

我建议使用方法IXmlSerializable公开接口Serialize()。如果你需要一般性地引用它们(不知道它是ClassA或ClassB,你可以将它们转换或装入界面并调用方法。

通常,我只是将对象归为Serializable,并确保所有属性都可序列化,或者使用XmlIgnore / Nonserialized

对属性进行归属
[Serializable]
public class MyClass
{
     [Nonserialized]
     private DataTable _myProperty;
     [XmlIgnore]
     public DataTable MyProperty { get; set; }
}

答案 3 :(得分:0)

如果您完全依赖XML序列化,请不要使用泛型:

public static class ObjectXMLSerializer { 
  public static void Save(object objectToSerialize, string fileName) { 
    // ...
  } 
} 

或者,查看XmlSerializer课程,它可能已涵盖您的要求:

public static class ObjectXMLSerializer {
  public static void Save(object objectToSerialize, string fileName) {
    var serializer = new XmlSerializer(objectToSerialize.GetType());
    using (var stream = File.OpenWrite(fileName)) {
      serializer.Serialize(stream, objectToSerialize);
    }
  }
}

要反序列化,因为必须知道所需对象的编译时类型,所以可以在反序列化方法中使用泛型:

public static class ObjectXMLDeserializer {
  public static T Load<T>(string fileName) { 
    var serializer = new XmlSerializer(typeof(T));
    using (var stream = File.OpenRead(fileName)) {
      return (T)serializer.Deserialize(stream);
    }
  } 
}

答案 4 :(得分:0)

尽管您可能做错了,但您可以使用反射构造泛型类型和泛型类型的实例。例如,如果我想创建一个List<int>我可以写

Type t = typeof(List<>).MakeGenericType(typeof(int));
object list = Activator.CreateInstance(t);
// add an integer to list and get Count property        
t.GetMethod("Add").Invoke(list, new object[] {3});
int count = (int) t.GetProperty("Count").GetValue(list, null);

......这就是为什么每个人都会建议重新设计你的课程。