如何仅允许实现ICoreModifier接口的类修改单例Core属性?
限制单例Core的写入权限,仅允许特定接口实现类修改
编译时检查的最优方案(推荐)
核心思路是用标记接口标识有权限的类,同时将Core的修改逻辑封装到需要该接口实例作为参数的方法中,让编译器自动拦截非法调用。
实现代码
// 标记接口:无需定义任何成员,仅用于标识权限 public interface ICoreModifier { } public class Core { // 单例实现 private static readonly Core _instance = new Core(); public static Core Instance => _instance; // 对外暴露只读属性 public int Property { get; private set; } // 仅接受实现ICoreModifier的类调用 public void SetProperty(int value, ICoreModifier modifier) { if (modifier == null) throw new ArgumentNullException(nameof(modifier)); Property = value; } } // 有权限的类:实现ICoreModifier public class A : ICoreModifier { public void UpdateCoreConfig() { // 合法调用:传递自身实例作为权限凭证 Core.Instance.SetProperty(1, this); } } // 无权限的类:未实现ICoreModifier public class B { public void TryUpdateCore() { // 编译错误:无法将B类型转换为ICoreModifier Core.Instance.SetProperty(1, this); } }
方案说明
- ICoreModifier的作用:作为标记接口,不需要定义任何方法/属性,它的存在仅仅是告诉编译器“这个类拥有修改Core的权限”,完美契合你想要的“can-do”关系。
- 编译时拦截:当未实现ICoreModifier的类尝试调用
SetProperty时,编译器会直接报错,因为无法将该类的实例转换为ICoreModifier类型,从根源上阻止非法写入。 - 避免权限滥用:修改逻辑被封装在专门的方法中,不会直接暴露可写属性,同时参数
modifier可以确保调用者确实是权限类的实例(避免伪造接口实例的情况)。
运行时检查方案(不推荐)
如果一定要通过属性setter实现写入,只能通过运行时检查调用者类型,但这种方式存在性能和健壮性问题:
实现代码
public interface ICoreModifier { } public class Core { private static readonly Core _instance = new Core(); public static Core Instance => _instance; private int _property; public int Property { get => _property; set { // 获取调用者类型 var stackTrace = new System.Diagnostics.StackTrace(); var callingMethod = stackTrace.GetFrame(1)?.GetMethod(); var callingType = callingMethod?.DeclaringType; // 检查调用者是否实现了ICoreModifier if (callingType == null || !typeof(ICoreModifier).IsAssignableFrom(callingType)) { throw new InvalidOperationException("仅实现ICoreModifier的类可修改此属性"); } _property = value; } } }
方案缺点
- 无编译时检查:非法调用只会在运行时抛出异常,无法提前发现问题。
- 性能损耗:每次写入都需要遍历调用栈、反射检查类型,对性能有一定影响。
- 可绕过:如果调用者通过一个实现了ICoreModifier的中间类转发写入操作,就能绕过检查,安全性不足。
总结
优先选择标记接口+带权限参数的修改方法的方案,既能实现编译时的权限拦截,又符合你期望的“can-do”接口语义,结构清晰且健壮。
内容的提问来源于stack exchange,提问作者Visual Studio
相关产品推荐
相关产品推荐

