在编译时限制方法访问的最佳方法是什么?
本文关键字:方法 最佳 是什么 访问 编译 | 更新日期: 2023-09-27 17:53:22
假设我有一个Manager类
public class Manager {
public Item Create() {
...
return new Item(...);
}
}
和Item类:
public class Item {
[AllowCallBy(typeof(Manager))]
public Item(...) {
}
...
}
现在,我想使用最简单和最直接的方法在编译时分析属性(如AllowCallBy
)并显示错误或警告。如果,在这种特殊情况下,一个非Manager类的类试图用new Item(...)
实例化Item
,我希望显示类似"不要直接实例化Item类,而是调用Manager. create(…)"的内容。
我想至少有一个系统:Roslyn, ReSharper, PostSharp或其他东西可以让我做到这一点,或者非常接近我想要达到的目标。谁能举个例子说明用什么和怎么用?
这绝对是@Habib提到的代码气味(有人能链接到一个特定的吗?),但是没有一个更完整的例子,很难提供超出已经在评论中建议的替代方案。我鼓励你扩大你的样品或重新考虑你的设计。
但是,我可以提供一个我过去使用过的选项,尽管不是用于此目的。您可以将Item
的构造函数标记为Obsolete
:
public class Item {
[Obsolete("Don't instantiate Item class directly, call Manager.Create(...) instead")]
public Item(...) {
}
...
}
然后在Manager
类中,在调用构造函数时特别忽略此警告:
public class Manager {
public Item Create() {
...
#pragma warning disable 618
return new Item(...);
#pragma warning restore 618
}
}
这样,每当有人试图在代码的其他地方创建自己的Item
时,他们将得到一个2级CS0618警告,指示他们不应该使用该方法(注意,我没有说不能)与属性中输入的文本完全相同。如果将警告作为错误启用(针对所有警告或仅此警告),那么它将像您最初希望的那样是一个编译错误。
请注意,没有什么可以阻止其他人添加这些pragma
语句来解决错误。然而,有了这个方法,开发人员不能说他们不知道他们不应该使用构造函数。
让我大吃一惊。PostSharp让你做你正在寻找的东西。简而言之,您将使用ComponentInternalAttribute
来控制类型的可见性:
public class Item {
[ComponentInternal(typeof(Manager))]
public Item(...) {
}
...
}
根据上面链接的他们的文档,试图在Manager
之外调用Item
的构造函数将产生编译时警告:
方法项目。由于[ComponentInternal]约束,不能从[其他方法]引用actor。
您可以通过更改属性的严重性级别使其为错误:
public class Item {
[ComponentInternal(typeof(Manager), Severity = SeverityType.Error)]
public Item(...) {
}
...
}
有比当前方法更好的方法来实现你的目标,考虑到你实际上可以更改代码。
例如,你可以将Item类的构造函数标记为私有,并向Item类添加一个静态工厂方法,该方法将负责创建类的实例。
另一种方法是将Item类移动到另一个程序集中,将其构造函数标记为内部,并实现另一个类(工厂),该类负责创建不同的Item对象。然后,您的类从其他程序集中可见,但不能直接实例化,因此强制代码用户使用提供的工厂。