有人尝试过实现c#吗?自动属性,它将在会话中存储值

本文关键字:属性 会话 存储 实现 | 更新日期: 2023-09-27 18:13:57

我喜欢在代码中使用c# Auto-Property,因为我发现它更好。最近有了一个想法,我将如何使用Auto-Property,但存储在会话的值。原因很简单:-避免会话项名称输入错误避免额外的代码-可能扩展到其他存储,如ViewState等

到目前为止,我认为属性将是最好的选择。只是好奇在我深入研究并开始实现它之前是否有人尝试过。

[Session] 
public int Id{get;set;}

代替

public int Id{ get{return Session["Id"];} set{Session["Id"] = value;}}

有人尝试过实现c#吗?自动属性,它将在会话中存储值

不行,你不能这么做。

自动实现的属性只有当期望的实现是一个由字段支持的"琐碎"属性时,才能工作。这就是编译器支持的全部内容。要"调整"一个自动实现的属性,唯一的方法就是以不同的方式设置getter和setter的可访问性。

当然,现在您可以编写代码,在创建时自动加载会话中的值,并在特定的方法调用时将其保存到会话中——但这实际上不是一回事。

你不能在普通的c#中这样做,但你可以通过方面得到你想要的效果。

Postsharp是AOP的一个很好的起点:

http://www.sharpcrafters.com/

您不能像其他人所说的那样使用自动实现的属性来做到这一点。但是你可以使用抽象属性和Castle DynamicProxy(或类似的)做一些非常类似的事情。

例如,您可以编写这样的代码:

public abstract class Foo : IWithSession
{
    public IDictionary<string, object> Session { get; private set; }
    protected Foo()
    {
        Session = new Dictionary<string, object>();
    }
    [Session]
    public abstract int Id { get; set; }
}

实际实现getter和setter的拦截器应该是这样的:

class SessionInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        var method = invocation.Method;
        bool isGetter = method.IsSpecialName && method.Name.StartsWith("get_");
        bool isSetter = method.IsSpecialName && method.Name.StartsWith("set_");
        if (isGetter || isSetter)
        {
            string propertyName = method.Name.Substring(4);
            var property = invocation.TargetType.GetProperty(propertyName);
            bool hasSessionAttribute = property.GetCustomAttributes(typeof(SessionAttribute), false).Any();
            if (hasSessionAttribute)
            {
                var session = ((IWithSession)invocation.InvocationTarget).Session;
                if (isGetter)
                {
                    invocation.ReturnValue = session[propertyName];
                    return;
                }
                else
                {
                    session[propertyName] = invocation.Arguments[0];
                    return;
                }
            }
        }
        invocation.Proceed();
    }
}