Sar*_*els 6 c# generics constraints xml-serialization
我有一个现有的类,用于序列化和反序列化XML中的对象.它是一个具有单个类型参数T的泛型类,其唯一约束是where T : IXmlSerializable.但是,我仍然希望能够在没有实现IXmlSerializable但具有该[Serializable]属性的类上使用此类.我怎么能这样做?
从我的通用类:
public static class XmlSerializationUtils<T> where T : IXmlSerializable
{
public static T DeserializeXml(XmlDocument xml) { ... }
public static XmlDocument SerializeToXml(T toSerialize) { ... }
}
Run Code Online (Sandbox Code Playgroud)
我发现了这个讨论,但没有给出解决方案,只是我做不到where T : Serializable.试图做的where T : SerializableAttribute是使Visual Studio说"不能使用密封类'System.SerializableAttribute'作为类型参数约束".
编辑:根据Stephen的回答,我删除了约束XmlSerializationUtils<T>并添加了这个静态构造函数:
static XmlSerializationUtils()
{
Type type = typeof(T);
bool hasAttribute = null != Attribute.GetCustomAttribute(type,
typeof(SerializableAttribute));
bool implementsInterface =
null != type.GetInterface(typeof(IXmlSerializable).FullName);
if (!hasAttribute && !implementsInterface)
{
throw new ArgumentException(
"Cannot use XmlSerializationUtils on class " + type.Name +
" because it does not have the Serializable attribute " +
" and it does not implement IXmlSerializable"
);
}
}
Run Code Online (Sandbox Code Playgroud)
您可以使用对象类型的IsSerializable属性检查类型是否可序列化.
myObj.GetType().IsSerializable
Run Code Online (Sandbox Code Playgroud)
如前所述,这不可能作为通用约束添加,但最有可能在构造函数中进行检查.
我只是消除了类型约束并在类型没有正确序列化或反序列化时捕获SerializationException ...实际上,这允许您的通用Serialize和Deserialize方法接受格式化程序
public enum Formatter { Binary, Xml }
Run Code Online (Sandbox Code Playgroud)
这可以控制序列化是二进制还是Xml
public class Serialization
{
public enum Formatter { Binary, Xml }
#region Serialization methods
public static void Serialize2File<T>(T obj, string pathSpec,
Formatter formatter)
{
try
{
switch (formatter)
{
case (Formatter.Binary):
using (var fs = new FileStream(pathSpec, FileMode.Create,
FileAccess.Write, FileShare.Write))
(new BinaryFormatter()).Serialize(fs, obj);
break;
case (Formatter.Xml):
var serializer = new XmlSerializer(typeof(T));
TextWriter textWriter = new StreamWriter(pathSpec);
serializer.Serialize(textWriter, obj);
textWriter.Close();
break;
default:
throw new MyCustomException("Invalid Formatter option");
}
}
catch (SerializationException sX)
{
var errMsg = String.Format(
"Unable to serialize {0} into file {1}",
obj, pathSpec);
throw new MyCustomException(errMsg, sX);
}
}
public static T DeSerializeFromFile<T>(string pathSpec,
Formatter formatter) where T : class
{
try
{
switch (formatter)
{
case (Formatter.Binary):
using (var strm = new FileStream(pathSpec,
FileMode.Open, FileAccess.Read))
{
IFormatter fmt = new BinaryFormatter();
var o = fmt.Deserialize(strm);
if (!(o is T))
throw new ArgumentException("Bad Data File");
return o as T;
}
case (Formatter.Xml):
var serializer = new XmlSerializer(typeof(T));
TextReader rdr = new StreamReader(pathSpec);
return (T)serializer.Deserialize(rdr);
default:
throw new MyCustomException("Invalid Formatter option");
}
}
catch (SerializationException sX)
{
var errMsg = String.Format(
"Unable to deserialize {0} from file {1}",
typeof(T), pathSpec);
throw new MyCustomException(errMsg, sX);
}
}
#endregion Serialization methods
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9035 次 |
| 最近记录: |