c# - 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
不共享相同User
或Role[]
对象。我们认为他们不会,但想检查一下。
解决方案
您将线程安全性与跨对象实例共享变量的能力混为一谈。实例变量也可以是非线程安全的,并且不是线程安全的仅意味着无法保证跨线程的变量值。
据我了解,您正在寻找的是“安全”的两种情况中的后一种:例如,该方法是否可以返回另一个用户对象的角色。答案是:不,除非该扩展方法从静态(共享)变量中提取。在您的示例中,它从它正在扩展的类的实例中提取其值,这意味着它不会获取另一个实例的值。
另一种方法是:扩展方法不是确定对象的状态,而是属性(在这种情况下IsInRole
)。由于该属性是通过实例成员调用的,因此您不必担心在这里返回错误的值。
“我们的理解正确吗?”:是的。实际上你已经在你的帖子中给出了正确的答案,只是换句话说。
推荐阅读
- android - android Kollin 应用程序中的“NetworkOnMainThreadException”使用由 swagger 生成的 kotlin-generated-client 文件
- python - “混合模型”的模型记录(例如,包括 KerasWrapper 的 SKlearn 管道)可能吗?
- scala - 即使以前的作业仍在 rundeck 上执行,如何启动预定的火花作业?
- ios - 如何使用本地 linhpone SDK for IOS 编译 linphone
- ios - 由于特殊字符,JSON Array 没有被解析并得到错误代码,如何忽略它们?
- java - 将 Spring 的健康指标映射到指标
- angular - 我怎样才能在角材料表中行跨度和跨度
- c++ - 从共享缓冲区写入文件丢失数据并且程序在没有 cout 的情况下崩溃
- python - Pyinstaller编译的PyQt5应用使用MacOS系统外观
- tensorflow - 在一个环境中安装了 tensorflow,现在导入不起作用