| File: Windows\Win32\Foundation\IHandle.cs | Web Access |
| Project: src\winforms\src\System.Private.Windows.Core\src\Microsoft.Private.Windows.Core.csproj (Microsoft.Private.Windows.Core) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. namespace Windows.Win32.Foundation; /// <summary> /// Used to abstract access to classes that contain a potentially owned handle. /// </summary> /// <remarks> /// <para> /// The key benefit of this is that we can keep the owning class from being collected during interop calls. /// <see cref="HandleRef"/> wraps arbitrary owners with target handles. Having this interface allows implicit use /// of the classes (such as System.Windows.Forms.Control) that meet this common pattern in interop and encourages /// correct alignment with the proper owner. /// </para> /// <para> /// Note that keeping objects alive is necessary ONLY when the object has a finalizer that will explicitly /// close the handle. /// </para> /// <para> /// When implementing P/Invoke wrappers that take this interface they should not directly take /// <see cref="IHandle{THandle}"/>, but should take a generic "T" that is constrained to IHandle{T}. Doing /// it this way prevents boxing of structs. The "T" parameters should also be marked as <see langword="in"/> /// to allow structs to be passed by reference instead of by value. /// </para> /// <para> /// When implementing this on a struct it is important that either the struct itself is marked as readonly /// or these properties are to avoid extra struct copies. /// </para> /// </remarks> internal interface IHandle<THandle> where THandle : unmanaged { THandle Handle { get; } /// <summary> /// Owner of the <see cref="Handle"/> that might close it when finalized. Default is the /// <see cref="IHandle{THandle}"/> implementer. /// </summary> /// <remarks> /// <para> /// This allows decoupling the owner from the <typeparamref name="THandle"/> provider and avoids boxing when /// <see cref="IHandle{THandle}"/> is on a struct. See <see cref="HandleRef{THandle}"/> for a concrete usage. /// </para> /// </remarks> #if NET object? Wrapper => this; #else object? Wrapper { get; } #endif }