繁体   English   中英

如何在C#中像Python一样编写函数装饰器

[英]How to write function decorator in c# like python

我已经在python上工作了一段时间,然后回到c#进行了一个项目。 所以我以前使用python语言,这迫使我像python程序员一样思考,我喜欢这个!

我想问的问题是如何创建一个在decarator之后调用的方法?

Python装饰器语法:

def p_decorate(func):
   def func_wrapper(name):
       return "<p>{0}</p>".format(func(name))
   return func_wrapper

@p_decorate
def get_text(name):
   return "lorem ipsum, {0} dolor sit amet".format(name)

我已经用谷歌搜索,但是只找到.Net 属性 ,它不能帮助我。

示例代码,但我想编写自己的AuthorizationAttribute类。

public class RestrictAccessToAssignedManagers : AuthorizationAttribute
{
    protected override AuthorizationResult IsAuthorized(System.Security.Principal.IPrincipal principal, AuthorizationContext authorizationContext)
    {
        EmployeePayHistory eph = (EmployeePayHistory)authorizationContext.Instance;
        Employee selectedEmployee;
        Employee authenticatedUser;

        using (AdventureWorksEntities context = new AdventureWorksEntities())
        {
            selectedEmployee = context.Employees.SingleOrDefault(e => e.EmployeeID == eph.EmployeeID);
            authenticatedUser = context.Employees.SingleOrDefault(e => e.LoginID == principal.Identity.Name);
        }

        if (selectedEmployee.ManagerID == authenticatedUser.EmployeeID)
        {
            return AuthorizationResult.Allowed;
        }
        else
        {
            return new AuthorizationResult("Only the authenticated manager for the employee can add a new record.");
        }
    }
}

[RestrictAccessToAssignedManagers]
public void InsertEmployeePayHistory(EmployeePayHistory employeePayHistory)
{
    if ((employeePayHistory.EntityState != EntityState.Detached))
    {
        this.ObjectContext.ObjectStateManager.ChangeObjectState(employeePayHistory, EntityState.Added);
    }
    else
    {
        this.ObjectContext.EmployeePayHistories.AddObject(employeePayHistory);
    }
}

来自MSDN的示例代码

通常在面向方面的编程中使用,可以做到这一点的两个流行的库是PostSharpFody

这是原始Python示例的PostSharp示例。

using System;
using System.Reflection;
using PostSharp.Aspects;
using PostSharp.Extensibility;

namespace SandboxConsole
{
    class Program
    {

        static void Main(string[] args)
        {
            Console.WriteLine(GetText("Test"));
            Console.ReadLine();
        }

        [Decorate]
        public static string GetText(string name)
        {
            return String.Format("lorem ipsum, {0} dolor sit amet", name);
        }
    }

    [Serializable]
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
    public class DecorateAttribute : MethodInterceptionAspect
    {
        public override bool CompileTimeValidate(MethodBase method)
        {
            if (!((MethodInfo)method).ReturnType.IsAssignableFrom(typeof(string)))
            {
                Message.Write(SeverityType.Error, "CUSTOM01", "Can not apply [Decorate] to method {0} because it does not retun a type that is assignable from string.", method);
                return false;
            }
            return true;
        }

        public override void OnInvoke(MethodInterceptionArgs args)
        {
            args.Proceed();
            args.ReturnValue = String.Format("<p>{0}</p>", args.ReturnValue);
        }
    }
}

您可以使用nuget包: CompileTimeWeaver.Fody

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM