inversionhourglass / Rougamo

Compile-time AOP component. Works with any method, whether it is async or sync, instance or static. Uses an aspectj-like pattern to match methods.
MIT License
393 stars 47 forks source link

请问是否未支持使用泛型特性? #63

Closed YooRarely closed 5 months ago

YooRarely commented 7 months ago

public class TryCatchAttribute : MoAttribute public class TryCatchAttribute<T> : MoAttribute

我设置了这样两条特性,TryCatchAttribute 可以正常使用 但是 TryCatchAttribute<T> 出错。 代码上他们长这样

    [TryCatch]
    public int Do(int t = 5)
    {
        throw new("");
    }
    [TryCatch<int>]
    public int Do2(int t = 5)
    {
        throw new("");
    }
Unhandled exception. System.TypeLoadException: Could not load type 'AOPUtil.TryCatchAttribute`1' from assembly 'Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

我通过ILSPY查看源码 【正常版本 TryCatchAttribute

   [TryCatch]
    public int Do(int t = 5)
    {
        TryCatchAttribute tryCatchAttribute = new TryCatchAttribute();
        IMo[] mos = new IMo[1] { tryCatchAttribute };
        MethodContext methodContext = new MethodContext(this, typeof(Class2), MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/, typeof(Class2).TypeHandle), isAsync: false, isIterator: false, mosNonEntryFIFO: false, mos, new object[1] { t });
        try
        {
            throw new Exception("");
        }
        catch (Exception exception)
        {
            methodContext.Exception = exception;
            tryCatchAttribute.OnException(methodContext);
            if (methodContext.ExceptionHandled)
            {
                return (int)methodContext.ReturnValue;
            }
            throw;
        }
    }

错误版本 TryCatchAttribute<T>

   [TryCatch<int>]
    public int Do2(int t = 5)
    {
        TryCatchAttribute<> tryCatchAttribute = (TryCatchAttribute<>)(object)new TryCatchAttribute<int>();
        IMo[] mos = new IMo[1] { tryCatchAttribute };
        MethodContext methodContext = new MethodContext(this, typeof(Class2), MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/, typeof(Class2).TypeHandle), isAsync: false, isIterator: false, mosNonEntryFIFO: false, mos, new object[1] { t });
        try
        {
            throw new Exception("");
        }
        catch (Exception exception)
        {
            methodContext.Exception = exception;
            ((TryCatchAttribute<T>)(object)tryCatchAttribute).OnException(methodContext);
            if (methodContext.ExceptionHandled)
            {
                return (int)methodContext.ReturnValue;
            }
            throw;
        }
    }

IL

    .method public hidebysig 
        instance int32 Do (
            [opt] int32 t
        ) cil managed 
    {
        .custom instance void [AOPUtil]AOPUtil.TryCatchAttribute::.ctor() = (
            01 00 00 00
        )
        .param [1] = int32(5)
        // Method begins at RVA 0x2200
        // Header size: 12
        // Code size: 147 (0x93)
        .maxstack 11
        .locals (
            [0] class [AOPUtil]AOPUtil.TryCatchAttribute,
            [1] class [Rougamo]Rougamo.Context.MethodContext,
            [2] bool,
            [3] class [System.Runtime]System.Exception,
            [4] int32,
            [5] class [Rougamo]Rougamo.IMo[]
        )

        // loop start
            IL_0000: newobj instance void [AOPUtil]AOPUtil.TryCatchAttribute::.ctor()
            IL_0005: stloc.0
            IL_0006: ldc.i4.1
            IL_0007: newarr [Rougamo]Rougamo.IMo
            IL_000c: dup
            IL_000d: ldc.i4.0
            IL_000e: ldloc.0
            IL_000f: stelem.ref
            IL_0010: stloc.s 5
            IL_0012: ldarg.0
            IL_0013: ldtoken Test.Class2
            IL_0018: call class [System.Private.CoreLib]System.Type [System.Private.CoreLib]System.Type::GetTypeFromHandle(valuetype [System.Private.CoreLib]System.RuntimeTypeHandle)
            IL_001d: ldtoken method instance int32 Test.Class2::Do(int32)
            IL_0022: ldtoken Test.Class2
            IL_0027: call class [System.Private.CoreLib]System.Reflection.MethodBase [System.Private.CoreLib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype [System.Private.CoreLib]System.RuntimeMethodHandle, valuetype [System.Private.CoreLib]System.RuntimeTypeHandle)
            IL_002c: ldc.i4.0
            IL_002d: ldc.i4.0
            IL_002e: ldc.i4.0
            IL_002f: ldloc.s 5
            IL_0031: ldc.i4.1
            IL_0032: newarr [System.Runtime]System.Object
            IL_0037: dup
            IL_0038: ldc.i4.0
            IL_0039: ldarg.1
            IL_003a: box [System.Runtime]System.Int32
            IL_003f: stelem.ref
            IL_0040: newobj instance void [Rougamo]Rougamo.Context.MethodContext::.ctor(object, class [netstandard]System.Type, class [netstandard]System.Reflection.MethodBase, bool, bool, bool, class [Rougamo]Rougamo.IMo[], object[])
            IL_0045: stloc.1
            .try
            {
                IL_0046: nop
                IL_0047: ldstr ""
                IL_004c: newobj instance void [System.Runtime]System.Exception::.ctor(string)
                IL_0051: throw
            } // end .try
            catch [System.Runtime]System.Exception
            {
                IL_0052: stloc.3
                IL_0053: ldloc.1
                IL_0054: ldloc.3
                IL_0055: callvirt instance void [Rougamo]Rougamo.Context.MethodContext::set_Exception(class [netstandard]System.Exception)
                IL_005a: ldloc.0
                IL_005b: ldloc.1
                IL_005c: callvirt instance void [AOPUtil]AOPUtil.TryCatchAttribute::OnException(class [Rougamo]Rougamo.Context.MethodContext)
                IL_0061: ldloc.1
                IL_0062: callvirt instance bool [Rougamo]Rougamo.Context.MethodContext::get_ExceptionHandled()
                IL_0067: brfalse.s IL_0078

                IL_0069: ldloc.1
                IL_006a: callvirt instance object [Rougamo]Rougamo.Context.MethodContext::get_ReturnValue()
                IL_006f: unbox.any [System.Runtime]System.Int32
                IL_0074: stloc.s 4
                IL_0076: leave.s IL_0090

                IL_0078: rethrow
            } // end handler
            IL_007a: ldloc.1
            IL_007b: callvirt instance bool [Rougamo]Rougamo.Context.MethodContext::get_HasException()
            IL_0080: brtrue IL_0000

            IL_0085: ldloc.1
            IL_0086: callvirt instance bool [Rougamo]Rougamo.Context.MethodContext::get_ExceptionHandled()
            IL_008b: brtrue IL_0000
        // end loop

        IL_0090: ldloc.s 4
        IL_0092: ret
    } // end of method Class2::Do
    .method public hidebysig 
        instance int32 Do2 (
            [opt] int32 t
        ) cil managed 
    {
        .custom instance void class [AOPUtil]AOPUtil.TryCatchAttribute`1<int32>::.ctor() = (
            01 00 00 00
        )
        .param [1] = int32(5)
        // Method begins at RVA 0x22b0
        // Header size: 12
        // Code size: 147 (0x93)
        .maxstack 11
        .locals (
            [0] class [AOPUtil]AOPUtil.TryCatchAttribute`1,
            [1] class [Rougamo]Rougamo.Context.MethodContext,
            [2] bool,
            [3] class [System.Runtime]System.Exception,
            [4] int32,
            [5] class [Rougamo]Rougamo.IMo[]
        )

        // loop start
            IL_0000: newobj instance void class [AOPUtil]AOPUtil.TryCatchAttribute`1<int32>::.ctor()
            IL_0005: stloc.0
            IL_0006: ldc.i4.1
            IL_0007: newarr [Rougamo]Rougamo.IMo
            IL_000c: dup
            IL_000d: ldc.i4.0
            IL_000e: ldloc.0
            IL_000f: stelem.ref
            IL_0010: stloc.s 5
            IL_0012: ldarg.0
            IL_0013: ldtoken Test.Class2
            IL_0018: call class [System.Private.CoreLib]System.Type [System.Private.CoreLib]System.Type::GetTypeFromHandle(valuetype [System.Private.CoreLib]System.RuntimeTypeHandle)
            IL_001d: ldtoken method instance int32 Test.Class2::Do2(int32)
            IL_0022: ldtoken Test.Class2
            IL_0027: call class [System.Private.CoreLib]System.Reflection.MethodBase [System.Private.CoreLib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype [System.Private.CoreLib]System.RuntimeMethodHandle, valuetype [System.Private.CoreLib]System.RuntimeTypeHandle)
            IL_002c: ldc.i4.0
            IL_002d: ldc.i4.0
            IL_002e: ldc.i4.0
            IL_002f: ldloc.s 5
            IL_0031: ldc.i4.1
            IL_0032: newarr [System.Runtime]System.Object
            IL_0037: dup
            IL_0038: ldc.i4.0
            IL_0039: ldarg.1
            IL_003a: box [System.Runtime]System.Int32
            IL_003f: stelem.ref
            IL_0040: newobj instance void [Rougamo]Rougamo.Context.MethodContext::.ctor(object, class [netstandard]System.Type, class [netstandard]System.Reflection.MethodBase, bool, bool, bool, class [Rougamo]Rougamo.IMo[], object[])
            IL_0045: stloc.1
            .try
            {
                IL_0046: nop
                IL_0047: ldstr ""
                IL_004c: newobj instance void [System.Runtime]System.Exception::.ctor(string)
                IL_0051: throw
            } // end .try
            catch [System.Runtime]System.Exception
            {
                IL_0052: stloc.3
                IL_0053: ldloc.1
                IL_0054: ldloc.3
                IL_0055: callvirt instance void [Rougamo]Rougamo.Context.MethodContext::set_Exception(class [netstandard]System.Exception)
                IL_005a: ldloc.0
                IL_005b: ldloc.1
                IL_005c: callvirt instance void [AOPUtil]AOPUtil.TryCatchAttribute`1::OnException(class [Rougamo]Rougamo.Context.MethodContext)
                IL_0061: ldloc.1
                IL_0062: callvirt instance bool [Rougamo]Rougamo.Context.MethodContext::get_ExceptionHandled()
                IL_0067: brfalse.s IL_0078

                IL_0069: ldloc.1
                IL_006a: callvirt instance object [Rougamo]Rougamo.Context.MethodContext::get_ReturnValue()
                IL_006f: unbox.any [System.Runtime]System.Int32
                IL_0074: stloc.s 4
                IL_0076: leave.s IL_0090

                IL_0078: rethrow
            } // end handler
            IL_007a: ldloc.1
            IL_007b: callvirt instance bool [Rougamo]Rougamo.Context.MethodContext::get_HasException()
            IL_0080: brtrue IL_0000

            IL_0085: ldloc.1
            IL_0086: callvirt instance bool [Rougamo]Rougamo.Context.MethodContext::get_ExceptionHandled()
            IL_008b: brtrue IL_0000
        // end loop

        IL_0090: ldloc.s 4
        IL_0092: ret
    } // end of method Class2::Do2
inversionhourglass commented 7 months ago

感谢反馈,将在后续版本中进行支持

inversionhourglass commented 5 months ago

已在3.0版本中支持