我在想如果我有一个常量属性,我能不能设置一个公共属性来封装它呢?
例如:
private const int DEFAULT_CHARGE = 200;
public int default_charge
{
get { return DEFAULT_CHARGE; }
}
我没有收到任何错误,但如果某些东西是常量,我真的不理解为什么要封装它。我真的想了解为什么这样做:
- 对/错
- 为什么要这样做?
- 好处是什么?
我在想如果我有一个常量属性,我能不能设置一个公共属性来封装它呢?
例如:
private const int DEFAULT_CHARGE = 200;
public int default_charge
{
get { return DEFAULT_CHARGE; }
}
我没有收到任何错误,但如果某些东西是常量,我真的不理解为什么要封装它。我真的想了解为什么这样做:
重要的是要知道常量会被编译器内联。这意味着以下两个示例将得到相同的程序:
private const int DEFAULT_CHARGE = 200;
public int default_charge
{
get { return DEFAULT_CHARGE; }
}
public int default_charge
{
get { return 200; }
}
如您所见,在编译后对DEFAULT_CHARGE
的引用已经丢失。在需要在多个项目中重复使用相同常量的解决方案中,这一点非常重要。
假设您将DEFAULT_CHARGE
作为public const
分别在LibA和LibB中使用。您的项目经理告诉您把值从200改为300。直觉地,您会去到定义了DEFAULT_CHARGE
的LibA,将其更改为300,然后重新编译和部署LibA。
结果是,现在LibA使用新值300而LibB仍使用旧值200,因为该常量在编译时被写入DLL中。
封装常量的原因是使您更轻松地更改其值。需求随时间而变化。今天是一个常数的DEFAULT_CHARGE
值可能在未来被替换为配置值。
通过封装常量,您还可以防止刚才我解释的问题。如果LibA、LibB(以及LibX、LibY、LibZ等)都依赖于封装,则只需要重新编译和部署LibA即可设置所有相关程序的默认费用。
private const double DEFAULT_CHARGE = 200.12345;
public int default_charge
{
get { return Math.round(DEFAULT_CHARGE,2); }
}
public interface IChargable {
int default_charge {get;}
}
public class MySimpleChargable: IChargable {
private const int DEFAULT_CHARGE = 200;
public int default_charge {get { return DEFAULT_CHARGE; }}
}
// Version 1.0
public class MyChargable {
private const int DEFAULT_CHARGE = 200;
//TODO: implement (rare) "some condition" case
public int default_charge {get { return DEFAULT_CHARGE; }}
}
// Version 1.1
public class MyChargable {
private const int DEFAULT_CHARGE = 200;
public int default_charge {
get {
if (some condition)
return SomeComputation();
return DEFAULT_CHARGE;
}
}
这取决于你的需求。
一般来说,属性旨在封装任何您想要的获取/设置逻辑,甚至是可计算的值或常量。
在我看来,公共属性返回私有常量的值在架构上是很好的,这种情况下使用您代码的人根本不知道他正在处理常量,即他从您的实现中抽象出来,这是很好的。如果您决定不将其作为常量而将其作为可配置值,则不会向库使用者公开它,只需将其设置为:
// private const int DEFAULT_CHARGE = 200; <-- is not used anymore
public int DefaultCharge
{
get { return SomeSortOfFileOrDatabaseConfiguration.DefaultCharge; }
}
或者甚至更好
public int DefaultCharge
{
get
{
return CurrentUser.PersonalSettings.DefaultCharge;
}
}
public int DefaultCharge
,并注意 Jeroen Mostert 在常量内联方面的评论。