< Summary

Information
Class: MyNet.Messaging.WeakFunc<T1, T2>
Assembly: MyNet.Messaging
File(s): https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.Messaging/WeakFunc.cs
Tag: 323_28699572109
Line coverage
86%
Covered lines: 33
Uncovered lines: 5
Coverable lines: 38
Total lines: 233
Line coverage: 86.8%
Branch coverage
60%
Covered branches: 24
Total branches: 40
Branch coverage: 60%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
.ctor(...)66.66%6690%
get_MethodName()83.33%66100%
get_IsAlive()50%1414100%
get_Target()50%22100%
get_FuncTarget()50%44100%
Execute()100%11100%
Execute(...)62.5%10869.23%
ExecuteWithObject(...)100%11100%
MarkForDeletion()100%11100%

File(s)

https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.Messaging/WeakFunc.cs

#LineLine coverage
 1// -----------------------------------------------------------------------
 2// <copyright file="WeakFunc.cs" company="Stéphane ANDRE">
 3// Copyright (c) Stéphane ANDRE. All rights reserved.
 4// </copyright>
 5// -----------------------------------------------------------------------
 6
 7using System;
 8using System.Reflection;
 9
 10namespace MyNet.Messaging;
 11
 12/// <summary>
 13/// Stores a Func&lt;TResult&gt; without causing a hard reference
 14/// to be created to the Function's owner. The owner can be garbage collected at any time.
 15/// </summary>
 16/// <typeparam name="TResult">The type of the result of the Func that will be stored by this weak reference.</typeparam>
 17public class WeakFunc<TResult>
 18{
 19    private Func<TResult?>? _staticFunc;
 20    private WeakReference? _targetReference;
 21    private WeakReference? _funcTargetReference;
 22    private object? _liveReference;
 23    private MethodInfo? _method;
 24
 25    public WeakFunc(Func<TResult?> func, bool keepTargetAlive = false)
 26        : this(func.Target, func, keepTargetAlive)
 27    {
 28    }
 29
 30    public WeakFunc(object? target, Func<TResult?> func, bool keepTargetAlive = false)
 31    {
 32        if (func.Method.IsStatic)
 33        {
 34            _staticFunc = func;
 35            if (target != null)
 36                _targetReference = new(target);
 37            return;
 38        }
 39
 40        _method = func.Method;
 41        _funcTargetReference = new(func.Target);
 42        _liveReference = keepTargetAlive ? func.Target : null;
 43        _targetReference = new(target);
 44    }
 45
 46    /// <summary>
 47    /// Gets a value indicating whether the WeakFunc is static or not.
 48    /// </summary>
 49    public bool IsStatic => _staticFunc != null;
 50
 51    /// <summary>
 52    /// Gets the name of the method that this WeakFunc represents.
 53    /// </summary>
 54    public string? MethodName => _staticFunc?.Method.Name ?? _method?.Name;
 55
 56    /// <summary>
 57    /// Gets a value indicating whether the Function's owner is still alive.
 58    /// </summary>
 59    public bool IsAlive =>
 60        (_staticFunc != null || _targetReference != null || _liveReference != null) && (_staticFunc != null ? _targetRef
 61
 62    /// <summary>
 63    /// Gets the Function's owner. This object is stored as a WeakReference.
 64    /// </summary>
 65    public object? Target => _targetReference?.Target;
 66
 67    protected object? FuncTarget => _liveReference ?? _funcTargetReference?.Target;
 68
 69    /// <summary>
 70    /// Executes the Func. This only happens if the Function's owner is still alive.
 71    /// </summary>
 72    /// <returns>The result of the Func stored as reference.</returns>
 73    public TResult? Execute()
 74    {
 75        if (!IsAlive)
 76            return default;
 77
 78        if (_staticFunc != null)
 79            return _staticFunc();
 80
 81        var funcTarget = FuncTarget;
 82        if (_method != null && funcTarget != null)
 83        {
 84            try
 85            {
 86                return (TResult?)_method.Invoke(funcTarget, null);
 87            }
 88            catch
 89            {
 90                return default;
 91            }
 92        }
 93
 94        return default;
 95    }
 96
 97    /// <summary>
 98    /// Sets all references to null, marking this WeakFunc for deletion.
 99    /// </summary>
 100    public void MarkForDeletion()
 101    {
 102        _targetReference = null;
 103        _funcTargetReference = null;
 104        _liveReference = null;
 105        _method = null;
 106        _staticFunc = null;
 107    }
 108}
 109
 110/// <summary>
 111/// Stores a Func without causing a hard reference to be created to the Function's owner.
 112/// The owner can be garbage collected at any time.
 113/// </summary>
 114/// <typeparam name="T">The type of the Function's parameter.</typeparam>
 115/// <typeparam name="TResult">The type of the Function's return value.</typeparam>
 116public class WeakFunc<T, TResult> : IExecuteWithObjectAndResult
 117{
 118    private Func<T?, TResult?>? _staticFunc;
 119    private WeakReference? _targetReference;
 120    private WeakReference? _funcTargetReference;
 121    private object? _liveReference;
 122    private MethodInfo? _method;
 123
 124    public WeakFunc(Func<T?, TResult?> func, bool keepTargetAlive = false)
 39125        : this(func.Target, func, keepTargetAlive)
 126    {
 39127    }
 128
 129    public WeakFunc(object? target, Func<T?, TResult?> func, bool keepTargetAlive = false)
 130    {
 45131        if (func.Method.IsStatic)
 132        {
 3133            _staticFunc = func;
 3134            if (target != null)
 0135                _targetReference = new(target);
 3136            return;
 137        }
 138
 42139        _method = func.Method;
 42140        _funcTargetReference = new(func.Target);
 42141        _liveReference = keepTargetAlive ? func.Target : null;
 42142        _targetReference = new(target);
 42143    }
 144
 145    /// <summary>
 146    /// Gets the name of the method that this WeakFunc represents.
 147    /// </summary>
 6148    public string? MethodName => _staticFunc?.Method.Name ?? _method?.Name;
 149
 150    /// <summary>
 151    /// Gets a value indicating whether the Function's owner is still alive.
 152    /// </summary>
 30153    public bool IsAlive => (_staticFunc != null || _targetReference != null || _liveReference != null) && (_staticFunc !
 154
 155    /// <summary>
 156    /// Gets the Function's owner. This object is stored as a WeakReference.
 157    /// </summary>
 6158    public object? Target => _targetReference?.Target;
 159
 18160    protected object? FuncTarget => _liveReference ?? _funcTargetReference?.Target;
 161
 162    /// <summary>
 163    /// Executes the Func. This only happens if the Function's owner is still alive.
 164    /// The Function's parameter is set to default(T).
 165    /// </summary>
 166    /// <returns>The result of the Func stored as reference.</returns>
 3167    public TResult? Execute() => Execute(default);
 168
 169    /// <summary>
 170    /// Executes the Func. This only happens if the Function's owner is still alive.
 171    /// </summary>
 172    /// <param name="parameter">A parameter to be passed to the function.</param>
 173    /// <returns>The result of the Func stored as reference.</returns>
 174    public TResult? Execute(T? parameter)
 175    {
 21176        if (!IsAlive)
 3177            return default;
 178
 18179        if (_staticFunc != null)
 180        {
 181            try
 182            {
 0183                return _staticFunc(parameter);
 184            }
 0185            catch
 186            {
 0187                return default;
 188            }
 189        }
 190
 18191        var funcTarget = FuncTarget;
 18192        if (_method != null && funcTarget != null)
 193        {
 194            try
 195            {
 18196                return (TResult?)_method.Invoke(funcTarget, [parameter]);
 197            }
 3198            catch
 199            {
 3200                return default;
 201            }
 202        }
 203
 0204        return default;
 18205    }
 206
 207    /// <summary>
 208    /// Executes the Func with a parameter of type object. This parameter
 209    /// will be cast to T. This method implements <see cref="IExecuteWithObjectAndResult.ExecuteWithObject" />
 210    /// and can be useful if you store multiple WeakFunc{T, TResult} instances but don't know in advance
 211    /// what type T represents.
 212    /// </summary>
 213    /// <param name="parameter">The parameter that will be passed to the Func after being cast to T.</param>
 214    /// <returns>The result of the execution as object, to be cast to TResult.</returns>
 215    public object? ExecuteWithObject(object? parameter)
 216    {
 9217        var parameterCasted = (T?)parameter;
 9218        return Execute(parameterCasted);
 219    }
 220
 221    /// <summary>
 222    /// Sets all references to null, marking this WeakFunc for deletion.
 223    /// </summary>
 224    public void MarkForDeletion()
 225    {
 9226        _staticFunc = null;
 9227        _targetReference = null;
 9228        _funcTargetReference = null;
 9229        _liveReference = null;
 9230        _method = null;
 9231    }
 232}
 233