How do I determine the HResult for a System.IO.IOException?

前端 未结 6 1667
Happy的楠姐
Happy的楠姐 2020-12-01 05:02

The System.Exception.HResult property is protected. How can I peek inside an exception and get the HResult without resorting to reflection or other ugly hacks?


相关标签:
6条回答
  • 2020-12-01 05:42

    You can also use the ISerializable interface:

    static class IOExceptionExtensions
    {
        public static int GetHResult(this IOException ex)
        {
            var info = new SerializationInfo(typeof (IOException), new FormatterConverter());
            ex.GetObjectData(info, new StreamingContext());
            return info.GetInt32("HResult");
        }
    }
    
    0 讨论(0)
  • 2020-12-01 05:48

    For .Net Framework 4.5 and above, you can use the Exception.HResult property:

    int hr = ex.HResult;
    

    For older versions, you can use Marshal.GetHRForException to get back the HResult, but this has significant side-effects and is not recommended:

    int hr = Marshal.GetHRForException(ex);
    
    0 讨论(0)
  • 2020-12-01 05:53

    For what it's worth, System.Exception.HResult is no longer protected in .NET 4.5 -- only the setter is protected. That doesn't help with code that might be compiled with more than one version of the framework.

    0 讨论(0)
  • 2020-12-01 05:58

    Have you profiled either of these cases? I'd imagine that the reflection method isn't all that slow, especially relative to all the other works your app will be doing and how often this exception will be likely to occur.

    If it turns out to be a bottleneck you can look into caching some of the reflection operations or generate dynamic IL to retrieve the property.

    0 讨论(0)
  • 2020-12-01 06:06

    Does CanRead property help in this case?
    i.e. call CanRead, if that returns true, call Read()

    0 讨论(0)
  • 2020-12-01 06:08

    Necromancing.
    Or you can just fetch the protected property by reflection:

    private static int GetHresult(System.Exception exception)
    {
        int retValue = -666;
    
        try
        {
            System.Reflection.PropertyInfo piHR = typeof(System.Exception).GetProperty("HResult", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public);
    
            if (piHR != null)
            {
                object o = piHR.GetValue(exception, null);
                retValue = System.Convert.ToInt32(o);
            }
        }
        catch (Exception ex)
        {
        }
    
        return retValue;
    }
    
    0 讨论(0)
提交回复
热议问题