User 对象上的静态扩展方法安全吗?

Are static extension methods on User object safe?

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

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

在我们的 controller/Razor 观点中,我们可以简单地说:

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

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

我们的理解对吗?谢谢。

更新: "Safe" 表示 IPrincipal 上的静态方法不共享相同的 UserRole[] 对象。我们认为他们不会,但想检查一下。

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

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

另一种方法是这样的:扩展方法不是确定对象的状态,属性(在本例中是 IsInRole)。由于 属性 是在实例成员上调用的,因此您不必担心 return 在这里输入错误的值。

"Are we correct in our understanding?":是的。其实你已经在你的post中给出了正确的答案,只是换句话说。