C# .net xml序列化-解析前检查文件

C# .net xml序列化-解析前检查文件,c#,.net,xml-serialization,C#,.net,Xml Serialization,我使用以下代码序列化xml文件 我想知道在这种情况下是否应该使用CanDeserialize功能 我注意到CanDeserialize在文件为空时抛出xmleexception 反序列化在这种情况下抛出InvalidOperationException 我的问题是,我是否应该删除额外的检查,如果反序列化执行某种检查 编辑:在阅读了一些评论和答案后,我想知道什么时候使用CanDeserialize public static T RestoreFromXml(string filename) {

我使用以下代码序列化xml文件

我想知道在这种情况下是否应该使用
CanDeserialize
功能

我注意到
CanDeserialize
在文件为空时抛出
xmleexception

反序列化
在这种情况下抛出
InvalidOperationException

我的问题是,我是否应该删除额外的检查,如果反序列化执行某种检查

编辑:在阅读了一些评论和答案后,我想知道什么时候使用
CanDeserialize

public static T RestoreFromXml(string filename)
{
    Object res = null;
    using (var stream = new FileStream(filename, FileMode.Open))
    {
        XmlReader reader = new XmlTextReader(stream);
        try
        {
            if (xs.CanDeserialize(reader))
            {
                res = xs.Deserialize(reader);
            }
        }
        catch (XmlException ex)
        {
            throw ex;
        }            
    }
    return (T)res;
}

您可以在尝试反序列化之前进行一些检查-检查文件名是否为null或空,检查文件是否存在,等等。下面是一些反序列化文件的代码:

/// <summary>
/// XML serializer helper class. Serializes and deserializes objects from/to XML
/// </summary>
/// <typeparam name="T">The type of the object to serialize/deserialize.
/// Must have a parameterless constructor and implement <see cref="Serializable"/></typeparam>
public class XmlSerializer<T> where T: class, new()
{
    /// <summary>
    /// Deserializes a XML file.
    /// </summary>
    /// <param name="filename">The filename of the XML file to deserialize</param>
    /// <returns>An object of type <c>T</c></returns>
    public static T DeserializeFromFile(string filename)
    {
        return DeserializeFromFile(filename, new XmlReaderSettings());
    }

    /// <summary>
    /// Deserializes a XML file.
    /// </summary>
    /// <param name="filename">The filename of the XML file to deserialize</param>
    /// <param name="settings">XML serialization settings. <see cref="System.Xml.XmlReaderSettings"/></param>
    /// <returns>An object of type <c>T</c></returns>
    public static T DeserializeFromFile(string filename, XmlReaderSettings settings)
    {
        if (string.IsNullOrEmpty(filename))
            throw new ArgumentException("filename", "XML filename cannot be null or empty");

        if (! File.Exists(filename))
            throw new FileNotFoundException("Cannot find XML file to deserialize", filename);

        // Create the stream writer with the specified encoding
        using (XmlReader reader = XmlReader.Create(filename, settings))
        {
            System.Xml.Serialization.XmlSerializer xmlSerializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
            return (T) xmlSerializer.Deserialize(reader);
        }
    }
} 
//
///XML序列化程序帮助程序类。从/到XML序列化和反序列化对象
/// 
///要序列化/反序列化的对象的类型。
///必须具有无参数构造函数和实现
公共类XmlSerializer,其中T:class,new()
{
/// 
///反序列化XML文件。
/// 
///要反序列化的XML文件的文件名
///T型物体
公共静态T反序列化FromFile(字符串文件名)
{
返回反序列化的FromFile(文件名,新的XmlReaderSettings());
}
/// 
///反序列化XML文件。
/// 
///要反序列化的XML文件的文件名
///XML序列化设置。
///T型物体
公共静态T反序列化FromFile(字符串文件名、XmlReaderSettings设置)
{
if(string.IsNullOrEmpty(文件名))
抛出新ArgumentException(“文件名”,“XML文件名不能为null或空”);
如果(!File.Exists(filename))
抛出新的FileNotFoundException(“找不到要反序列化的XML文件”,文件名);
//使用指定的编码创建流编写器
使用(XmlReader=XmlReader.Create(文件名、设置))
{
System.Xml.Serialization.XmlSerializer XmlSerializer=new System.Xml.Serialization.XmlSerializer(typeof(T));
返回(T)xmlSerializer.Deserialize(读取器);
}
}
} 
}

您可以这样使用它:

string filename = "...";

Foo foo = XmlSerializer<Foo>.DeserializeFromFile(filename);
string filename=“…”;
Foo Foo=XmlSerializer.DeserializeFromFile(文件名);
这段代码取自我写的一篇文章,你可以在这里找到:


我建议您使用CanDeserialize,以便抛出尽可能少的异常。当应用程序处于无法保护自己的异常状态时,应该有例外

你可以对警卫说同样的话。 为什么要检查:

if (value == null)
    return;
//do something
而不是:

try{
   // do something
catch()

这不是完全相同的事情,但我认为让应用程序尽可能不受异常的影响是一个好主意。

空文件不是要反序列化的valide文件,我认为您必须测试文件是否为空,然后输入try/catch代码。我想您可以根据您想要返回的信息级别来决定-如果您想告诉用户文件为空,请先检查文件。否则,只需使用
反序列化
。就我个人而言,我从未在
反序列化
调用之前使用过
CanDeserialize
,因为从反序列化引发的异常的InnerException非常明确。根级别的文件-{“数据”中的一个字符无效。第1行,位置1。“}空文件-{”根元素丢失。“}同意。我刚刚针对检查和捕获异常运行了一个性能测试,捕获异常花费了很长时间(实际上从未完成)并使我的CPU内核达到最大。检查只花了几秒钟。