如何在c#中编写函数装饰器,如python

时间:2016-07-13 14:15:30

标签: c# .net-4.5

我已经在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)

我用谷歌搜索但只找到了。Attributes它并没有帮助我。

示例代码,但我想编写自己的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

的示例代码

2 个答案:

答案 0 :(得分:1)

通常用于面向方面编程,两个流行的库是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);
        }
    }
}

答案 1 :(得分:0)

您可以使用nuget软件包:CompileTimeWeaver.Fody