首页 > 解决方案 > User 对象上的静态扩展方法是否安全?

问题描述

我们在 ASP.NET MVC 的User对象上创建了自定义扩展方法,例如:

public static bool IsInAnyRole(this IPrincipal principal, params Role[] roles)
{
    return roles.Select(x => x.ToString()).Any(principal.IsInRole);
}

在我们的控制器/Razor 视图中,我们可以简单地说:

if (User.IsInAnyRole(Role.SystemAdmin, Role.Management))
{
     // Do something...
}

SO上的各种帖子表明静态成员不是线程安全的,并且它们为整个应用程序创建一次。我们担心IPrincipal所有用户都会使用相同的方法,但我们认为这不可能发生,因为它是扩展方法的参数。唯一在所有用户中保持不变的是该方法的内部功能。

我们的理解正确吗?谢谢。

更新: “安全”意味着静态方法IPrincipal不共享相同UserRole[]对象。我们认为他们不会,但想检查一下。

标签: c#asp.net-mvcstaticextension-methods

解决方案


您将线程安全性与跨对象实例共享变量的能力混为一谈。实例变量也可以是非线程安全的,并且不是线程安全的仅意味着无法保证跨线程的变量值。

据我了解,您正在寻找的是“安全”的两种情况中的后一种:例如,该方法是否可以返回另一个用户对象的角色。答案是:不,除非该扩展方法从静态(共享)变量中提取。在您的示例中,它从它正在扩展的类的实例中提取其值,这意味着它不会获取另一个实例的值。

另一种方法是:扩展方法不是确定对象的状态,而是属性(在这种情况下IsInRole)。由于该属性是通过实例成员调用的,因此您不必担心在这里返回错误的值。

“我们的理解正确吗?”:是的。实际上你已经在你的帖子中给出了正确的答案,只是换句话说。


推荐阅读