• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

NetFabric / NetFabric.CodeAnalysis / 6130084901

09 Sep 2023 09:14AM UTC coverage: 83.158% (+0.2%) from 82.932%
6130084901

push

github

web-flow
Fixes (#27)

227 of 266 branches covered (0.0%)

Branch coverage included in aggregate %.

661 of 661 new or added lines in 31 files covered. (100.0%)

642 of 779 relevant lines covered (82.41%)

18.46 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.74
/NetFabric.Reflection/Expressions/ExpressionEx.Using.cs
1
using NetFabric.Reflection;
2
using System;
3
using System.Collections.Generic;
4
using System.Linq.Expressions;
5
using System.Reflection;
6
using static System.Linq.Expressions.Expression;
7

8
namespace NetFabric.Expressions;
9

10
public static partial class ExpressionEx
11
{
12
    /// <summary>
13
    /// Creates a <see cref="System.Linq.Expressions.TryExpression"/> that that ensures the correct use of <see cref="System.IDisposable"/> objects.
14
    /// </summary>
15
    /// <param name="instance">An <see cref="System.Linq.Expressions.ParameterExpression"/> that defines the object instance to be disposed.</param>
16
    /// <param name="body">The body of the <see cref="System.Linq.Expressions.TryExpression"/>.</param>
17
    /// <returns>The created <see cref="System.Linq.Expressions.TryExpression"/>.</returns>
18
    /// <exception cref="Exception">Object type does not disposable.</exception>
19
    /// <remarks>
20
    /// <p>
21
    /// <see cref="NetFabric.Expressions.ExpressionEx.Using(Expression,Expression)"/> ensures that <see cref="System.IDisposable.Dispose"/>
22
    /// is called even if an exception occurs within the body.
23
    /// </p>
24
    /// <p>
25
    /// The <see cref="System.Linq.Expressions.Expression"/> in property <see cref="System.Linq.Expressions.TryExpression.Finally"/> depends on if the object to
26
    /// be disposed is an <c>interface</c>, <c>class</c>, <c>struct</c> or <c>ref struct</c>.
27
    /// </p>
28
    /// <p>
29
    /// An object to be considered disposable has to implement <see cref="System.IDisposable"/>, except for <c>ref struct</c> for which is enough
30
    /// to a have a public parameterless method named Dispose.
31
    /// </p>
32
    /// </remarks>
33
    public static TryExpression Using(ParameterExpression instance, Expression body)
34
    {
35
        if (!instance.Type.IsDisposable(out var disposeMethodInfo, out var isByRefLike))
32✔
36
            throw new Exception($"'{instance.Type.Name}': type used in a using statement must be implicitly convertible to 'System.IDisposable'");
3✔
37

38
        return TryFinally(
29✔
39
            body,
29✔
40
            Dispose(disposeMethodInfo, instance, isByRefLike)
29✔
41
        );
29✔
42

43
        static Expression Dispose(MethodInfo disposeMethodInfo, ParameterExpression instance, bool isByRefLike)
44
        {
45
            return instance.Type switch
29✔
46
            {
29✔
47
                {IsValueType: true} when isByRefLike => DisposeByRefLikeType(disposeMethodInfo, instance),
22✔
48
                {IsValueType: true} => DisposeValueType(disposeMethodInfo, instance),
8✔
49
                _ => DisposeReferenceType(disposeMethodInfo, instance)
14✔
50
            };
29✔
51

52
            static Expression DisposeByRefLikeType(MethodInfo disposeMethodInfo, ParameterExpression instance)
53
                => Call(instance, disposeMethodInfo);
7✔
54

55
            static Expression DisposeValueType(MethodInfo disposeMethodInfo, Expression instance)
56
                => Call(instance, disposeMethodInfo);
8✔
57

58
            static Expression DisposeReferenceType(MethodInfo disposeMethodInfo, ParameterExpression instance)
59
                => IfThen(
14✔
60
                    NotEqual(instance, Constant(null)),
14✔
61
                    Call(Convert(instance, typeof(IDisposable)), disposeMethodInfo)
14✔
62
                );
14✔
63
        }
64
    }
65

66
    /// <summary>
67
    /// Creates a <see cref="System.Linq.Expressions.TryExpression"/> that that ensures the correct use of <see cref="System.IDisposable"/> objects.
68
    /// </summary>
69
    /// <param name="instances">A collection of <see cref="System.Linq.Expressions.Expression"/>, each defining an object instance to be disposed.</param>
70
    /// <param name="body">The body of the <see cref="System.Linq.Expressions.TryExpression"/>.</param>
71
    /// <returns>The created <see cref="System.Linq.Expressions.TryExpression"/>.</returns>
72
    /// <exception cref="Exception">Object type does not implement <see cref="System.IDisposable"/>.</exception>
73
    /// <remarks>
74
    /// <p>
75
    /// <see cref="NetFabric.Expressions.ExpressionEx.Using(IEnumerable&lt;ParameterExpression&gt;,Expression)"/> ensures that <see cref="System.IDisposable.Dispose"/>
76
    /// is called even if an exception occurs within the body.
77
    /// </p>
78
    /// <p>
79
    /// The <see cref="System.Linq.Expressions.Expression"/> in property <see cref="System.Linq.Expressions.TryExpression.Finally"/> depends on if the object to
80
    /// be disposed is an <c>interface</c>, <c>class</c>, <c>struct</c> or <c>ref struct</c>.
81
    /// </p>
82
    /// </remarks>
83
    public static TryExpression Using(IEnumerable<ParameterExpression> instances, Expression body)
84
    {
85
        TryExpression? result = default;
1✔
86
        // ReSharper disable once LoopCanBeConvertedToQuery
87
        foreach(var instance in instances)
6✔
88
        {
89
            result = Using(instance, result ?? body);
2✔
90
        }
91
        if (result is null) 
1!
92
            throw new ArgumentException($"Must be not empty.", nameof(instances));
×
93
        return result;
1✔
94
    }
95
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc