减去两个System.Runtime.InteropServices.ComTypes.FILETIME对象的最安全的方法是什么

时间:2011-01-16 18:56:59

标签: c# .net bitwise-operators overflowexception filetime

我想知道减去两个System.Runtime.InteropServices.ComTypes.FILETIME对象最安全的方法是什么?我使用了以下代码,但由于低32位值中的负数,有时它会给我ArithmaticOverflow异常。我不确定用unchecked封闭身体是否符合目的。如果没有得到任何运行时异常或CS0675警告消息,请给我一些安全的建议。

private static UInt64 SubtractTimes(FILETIME a, FILETIME b)
        {
            UInt64 aInt = ((UInt64)(a.dwHighDateTime << 32)) | (UInt32)a.dwLowDateTime;
            UInt64 bInt = ((UInt64)(b.dwHighDateTime << 32)) | (UInt32)b.dwLowDateTime;
            return aInt - bInt;
        }

2 个答案:

答案 0 :(得分:1)

您需要使用未选中来取消异常:

    public static long FileTime2Long(FILETIME ft) {
        uint low = unchecked((uint)ft.dwLowDateTime);
        return (long)ft.dwHighDateTime << 32 | low;
    }

    static void Test() {
        FILETIME ft = new FILETIME();
        ft.dwHighDateTime = 1;
        ft.dwLowDateTime = -1;
        long value = FileTime2Long(ft);
        Debug.Assert(value == 0x1ffffffff);
    }

如果需要,您可以使用DateTime.FromFileTimeUtc()转换为DateTime。

答案 1 :(得分:0)

您可以使用DateTime.FromFileTime()方法将FILETIME转换为DateTime对象,然后您可以安全地减去DateTime对象。

如果您遇到同样的问题,请使用以下方法,因为DateTime.FromFileTime()因签名/未签名问题而无法在所有情况下使用。

public static DateTime ToDateTime( System.Runtime.InteropServices.FILETIME ft )
{
  IntPtr buf = IntPtr.Zero;
  try 
  {
    long[] longArray = new long[1];
    int cb = Marshal.SizeOf( ft );
    buf = Marshal.AllocHGlobal( cb );
    Marshal.StructureToPtr( ft, buf, false );
    Marshal.Copy( buf, longArray, 0, 1 );
    return DateTime.FromFileTime( longArray[0] );
  }
  finally 
  {
    if ( buf != IntPtr.Zero ) Marshal.FreeHGlobal( buf );
  }
}