public static bool Is <TOut>(this object?input, [NotNullWhen(true)] out TOut?output) { // if (input is TOut temp) // { // output = temp; // return true; // } // else // { // output = default; // return false; // } Emit.Ldarg(nameof(input)); Emit.Isinst <TOut>(); Emit.Brfalse("isnot"); Emit.Ldarg(nameof(output)); Emit.Ldarg(nameof(input)); Emit.Unbox_Any <TOut>(); Emit.Stobj <TOut>(); Emit.Ldc_I4_1(); Emit.Ret(); MarkLabel("isnot"); Emit.Ldarg(nameof(output)); Emit.Initobj <TOut>(); Emit.Ldc_I4_0(); Emit.Ret(); throw Unreachable(); }
/// <summary> /// Sends a control code directly to a specified device driver, causing the corresponding device to perform the corresponding operation. /// </summary> /// <typeparam name="TIn">The type of the <paramref name="inVal"/>.</typeparam> /// <typeparam name="TOut">The type of the return value.</typeparam> /// <param name="hDevice"> /// A handle to the device on which the operation is to be performed. The device is typically a volume, directory, file, or stream. /// To retrieve a device handle, use the CreateFile function. For more information, see Remarks. /// </param> /// <param name="ioControlCode"> /// The control code for the operation. This value identifies the specific operation to be performed and the type of device on which /// to perform it. /// </param> /// <param name="inVal"> /// The input value required to perform the operation. The type of this data depends on the value of the <paramref /// name="ioControlCode"/> parameter. /// </param> /// <returns>An asynchronous result containing the populated data supplied by <typeparamref name="TOut"/>.</returns> /// <remarks> /// <para> /// To retrieve a handle to the device, you must call the CreateFile function with either the name of a device or the name of the /// driver associated with a device. To specify a device name, use the following format: /// </para> /// <para>\\.\DeviceName</para> /// <para> /// DeviceIoControl can accept a handle to a specific device. For example, to open a handle to the logical drive /// A: with CreateFile, specify \\.\a:. Alternatively, you can use the names \\.\PhysicalDrive0, \\.\PhysicalDrive1, and so on, to /// open handles to the physical drives on a system. /// </para> /// <para> /// You should specify the FILE_SHARE_READ and FILE_SHARE_WRITE access flags when calling CreateFile to open a handle to a device /// driver. However, when you open a communications resource, such as a serial port, you must specify exclusive access. Use the other /// CreateFile parameters as follows when opening a device handle: /// </para> /// <list type="bullet"> /// <item> /// <description>The fdwCreate parameter must specify OPEN_EXISTING.</description> /// </item> /// <item> /// <description>The hTemplateFile parameter must be NULL.</description> /// </item> /// <item> /// <description> /// The fdwAttrsAndFlags parameter can specify FILE_FLAG_OVERLAPPED to indicate that the returned handle can be used in overlapped /// (asynchronous) I/O operations. /// </description> /// </item> /// </list> /// </remarks> public static Task <TOut?> DeviceIoControlAsync <TIn, TOut>(HFILE hDevice, uint ioControlCode, TIn?inVal) where TIn : struct where TOut : struct { TOut?outValue = default(TOut); var buf = Pack(inVal, outValue); return(Task.Factory.FromAsync(BeginDeviceIoControl <TIn, TOut>, EndDeviceIoControl <TIn, TOut>, hDevice, ioControlCode, buf, null)); }
/// <inheritdoc cref="IDisposable.Dispose"/> public void Dispose() { if (!IsAlive) { return; } _handle.Updated -= OnUpdate; _handle.Deleted -= OnDelete; _cached = default; IsAlive = false; }
private static byte[] Pack <TIn, TOut>(TIn?inVal, TOut?outVal) where TIn : struct where TOut : struct { using (var ms = new MemoryStream()) using (var wtr = new BinaryWriter(ms)) { wtr.Write(inVal.HasValue ? Marshal.SizeOf(typeof(TIn)) : 0); wtr.Write(outVal.HasValue ? Marshal.SizeOf(typeof(TOut)) : 0); if (inVal.HasValue) { wtr.Write(inVal.Value); } if (outVal.HasValue) { wtr.Write(outVal.Value); } return(ms.ToArray()); } }
private bool TryRewriteStrict <TSyntax, TOut>(TSyntax?syntax, [NotNullIfNotNull("syntax")] out TOut?newSyntax) where TSyntax : SyntaxBase where TOut : SyntaxBase { if (syntax is null) { newSyntax = null; return(false); } var newSyntaxUntyped = RewriteInternal(syntax); var hasChanges = !object.ReferenceEquals(syntax, newSyntaxUntyped); if (newSyntaxUntyped is not TOut newSyntaxTyped) { throw new InvalidOperationException($"Expected {nameof(currentSyntax)} to be of type {typeof(TSyntax)}"); } newSyntax = newSyntaxTyped; return(hasChanges); }
public static TOut?Get <TOut, TKey, TValue>(this IDictionary <TKey, TValue> dictionary, TKey key, TOut?defaultValue = default) { if (dictionary is null || key is null) { return(default);
/// <summary>TODO</summary> public static int?CompareTo <TOut>(this TOut? @this, TOut?other) where TOut : struct, IComparable => (from lhs in @this from rhs in other select lhs.CompareTo(rhs)).ElseDefault();
/// <summary>TODO</summary> public static TOut?Max <TOut>(this TOut? @this, TOut?other) where TOut : struct, IComparable => from lhs in @this from rhs in other select lhs.CompareTo(rhs) < 0 ? lhs : rhs;
/// <summary>Executes <paramref name="action"/> on <paramref name="this"/> exactly if it has a value.</summary> /// <typeparam name="TOut">The struct basis for the rtuern type TOut?.</typeparam> /// <returns>Returns <paramref name="this"/>.</returns> public static TOut?IfHasValueDo <TOut>(this TOut? @this, Action <TOut> action) where TOut : struct => @this.HasValue ? @this.Match(value => { action(value); return(@this.Value); }, () => @this.Value) : null as TOut?;
/// <summary>TODO</summary> public static TOut?Where <TOut>(this TOut? @this, Func <TOut, bool> predicate) where TOut : struct => @this.Bind(e => predicate(e) ? e : default(TOut?));
/// <summary>Executes <paramref name="action"/> on <paramref name="this"/> exactly if it hasn't any value.</summary> /// <typeparam name="TOut">The struct basis for the rtuern type TOut?.</typeparam> /// <returns>Returns <paramref name="this"/>.</returns> public static TOut?ElseDo <TOut>(this TOut? @this, Action action) where TOut : struct => @this.Match(value => @this, () => { action(); return(@this); });
/// <summary>Returns the value of <paramref name="this"/> if it has one, otherwise throws an <see cref="InvalidOperationException"/>.</summary> /// <typeparam name="TOut">The struct basis for the rtuern type TOut?.</typeparam> /// <returns>Returns the value of <paramref name="this"/>.</returns> /// <exception cref="InvalidOperationException"></exception> public static TOut ForceGetValue <TOut>(this TOut? @this) where TOut : struct => @this.Match(e => e, () => { throw new InvalidOperationException(@this.ToString()); });
/// <summary>Returns the value of <paramref name="this">this</paramref> it it has one; otherwise returns <paramref name="alternate"/>().</summary> /// <typeparam name="TOut">The struct basis for the rtuern type TOut?.</typeparam> /// <param name="this">The <typeparamref name="TOut"/>? being operated upon.</param> /// <param name="alternate">The action to be perrofmed if <paramref name="this"/> has no value.</param> public static TOut?Else <TOut>(this TOut? @this, Func <TOut> alternate) where TOut : struct => @this.Match(e => e, alternate);
/// <summary>Returns the value of <paramref name="this">this</paramref> it it has one; otherwise returns default(<typeparamref name="TOut"/>).</summary> /// <typeparam name="TOut">The struct basis for the rtuern type TOut?.</typeparam> /// <param name="this">The <see cref="Maybe{T}"/> being operated upon.</param> public static TOut ElseDefault <TOut>(this TOut? @this) where TOut : struct => @this.Match(e => e, () => default(TOut));
/// <summary> /// Sends a control code directly to a specified device driver, causing the corresponding device to perform the corresponding operation. /// </summary> /// <typeparam name="TIn">The type of the <paramref name="inVal"/>.</typeparam> /// <typeparam name="TOut">The type of the <paramref name="outVal"/>.</typeparam> /// <param name="hDevice">A handle to the device on which the operation is to be performed. The device is typically a volume, directory, file, or stream. To retrieve a device /// handle, use the CreateFile function. For more information, see Remarks.</param> /// <param name="ioControlCode">The control code for the operation. This value identifies the specific operation to be performed and the type of device on which to perform it.</param> /// <param name="inVal">The input value required to perform the operation. The type of this data depends on the value of the <paramref name="ioControlCode"/> parameter.</param> /// <param name="outVal">The output value that is to receive the data returned by the operation. The type of this data depends on the value of the dwIoControlCode parameter.</param> /// <returns>An asynchronous result containing the populated data supplied by <paramref name="outVal"/>.</returns> /// <remarks> /// <para> /// To retrieve a handle to the device, you must call the CreateFile function with either the name of a device or the name of the driver associated with /// a device. To specify a device name, use the following format: /// </para> /// <para>\\.\DeviceName</para> /// <para> /// DeviceIoControl can accept a handle to a specific device. For example, to open a handle to the logical drive /// A: with CreateFile, specify \\.\a:. Alternatively, you can use the names \\.\PhysicalDrive0, \\.\PhysicalDrive1, and so on, to open handles to the /// physical drives on a system. /// </para> /// <para> /// You should specify the FILE_SHARE_READ and FILE_SHARE_WRITE access flags when calling CreateFile to open a handle to a device driver. However, when /// you open a communications resource, such as a serial port, you must specify exclusive access. Use the other CreateFile parameters as follows when /// opening a device handle: /// </para> /// <list type="bullet"> /// <item> /// <description>The fdwCreate parameter must specify OPEN_EXISTING.</description> /// </item> /// <item> /// <description>The hTemplateFile parameter must be NULL.</description> /// </item> /// <item> /// <description>The fdwAttrsAndFlags parameter can specify FILE_FLAG_OVERLAPPED to indicate that the returned handle can be used in overlapped (asynchronous) I/O operations.</description> /// </item> /// </list> /// </remarks> public static Task <TOut?> DeviceIoControlAsync <TIn, TOut>(HFILE hDevice, uint ioControlCode, TIn?inVal, TOut?outVal) where TIn : struct where TOut : struct { var buf = Pack(inVal, outVal); return(new TaskFactory().FromAsync(BeginDeviceIoControl <TIn, TOut>, EndDeviceIoControl <TIn, TOut>, hDevice, ioControlCode, buf, null)); }
public static TOut?TryTransform <TIn, TOut>(this TIn?instance, [NotNull] Func <TIn, TOut> transform, TOut?elseValue = null) where TIn : struct where TOut : struct { if (transform == null) { throw new ArgumentNullException(nameof(transform)); } if (instance == null) { return(elseValue); } return(transform(instance.Value)); }
public ResourceState(bool loading, TOut?data, Exception?exception) { Loading = loading; Data = data; Exception = exception; }
public static ResourceState FromData(TOut?data) => new ResourceState(false, data, null);
public static TOut?Get <TOut, TKey, TValue>(this IDictionary <TKey, TValue> dictionary, TKey key, TOut?defaultValue = default) { if (dictionary is null || key is null) { return(defaultValue); } if (!dictionary.ContainsKey(key)) { if (defaultValue is TValue value) { dictionary.Add(key, value); } return(defaultValue); } if (dictionary[key] is TOut o) { return(o); } return(defaultValue); }
public static Optional <TOut> FromNullable <TOut>(TOut?value) where TOut : struct { return(value.HasValue ? new Optional <TOut>(value.Value) : new Optional <TOut>()); }
public static IAsyncResult BeginDeviceIoControl <TIn, TOut>(SafeFileHandle hDevice, uint dwIoControlCode, TIn?inVal, TOut?outVal, AsyncCallback userCallback) where TIn : struct where TOut : struct { var buffer = Pack(inVal, outVal); return(BeginDeviceIoControl <TIn, TOut>(hDevice, dwIoControlCode, buffer, userCallback, null)); }
private static unsafe Task <TOut?> ExplicitDeviceIoControlAsync <TIn, TOut>(HFILE hDevice, uint ioControlCode, TIn?inVal, TOut?outVal) where TIn : struct where TOut : struct { #pragma warning disable CS0618 // Type or member is obsolete ThreadPool.BindHandle((IntPtr)hDevice); #pragma warning restore CS0618 // Type or member is obsolete var tcs = new TaskCompletionSource <TOut?>(); var buffer = Pack(inVal, outVal); var nativeOverlapped = new Overlapped().Pack((code, bytes, overlap) => { try { switch (code) { case Win32Error.ERROR_SUCCESS: outVal = Unpack <TIn, TOut>(buffer).Item2; tcs.TrySetResult(outVal); break; case Win32Error.ERROR_OPERATION_ABORTED: tcs.TrySetCanceled(); break; default: tcs.TrySetException(new Win32Exception((int)code)); break; } } finally { Overlapped.Unpack(overlap); Overlapped.Free(overlap); } }, buffer); var unpack = true; try { var inSz = Marshal.SizeOf(typeof(TIn)); fixed(byte *pIn = buffer, pOut = &buffer[inSz]) { uint bRet; var ret = DeviceIoControl(hDevice, ioControlCode, pIn, (uint)inSz, pOut, (uint)(buffer.Length - inSz), out bRet, nativeOverlapped); if (ret) { outVal = Unpack <TIn, TOut>(buffer).Item2; tcs.SetResult(outVal); return(tcs.Task); } } var lastWin32Error = Marshal.GetLastWin32Error(); if (lastWin32Error != Win32Error.ERROR_IO_PENDING && lastWin32Error != Win32Error.ERROR_SUCCESS) { throw new Win32Exception(lastWin32Error); } unpack = false; return(tcs.Task); } finally { if (unpack) { Overlapped.Unpack(nativeOverlapped); Overlapped.Free(nativeOverlapped); } } }
private void OnUpdate() { // Invalidate cache _cached = default; }