Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 封装私有常量_C#_Oop - Fatal编程技术网

C# 封装私有常量

C# 封装私有常量,c#,oop,C#,Oop,我只是想知道如果我有一个常量属性,我可以设置一个公共属性来封装它吗 e、 g 我没有得到任何错误,但是如果某个东西是常量,我真的不理解为什么要封装它。我真的很想知道为什么会这样: 对/错 为什么要这样做 福利 即使某些内容是常量,您仍然需要控制如何将其返回给调用方。如果您有一个双变量,该变量存储到小数点后5位,那么您可能希望在小数点后2位将值返回给调用方。封装帮助您获得对字段的这种控制 所以您可能需要像这样封装一个常量字段 private const double DEFAULT_CHARGE

我只是想知道如果我有一个常量属性,我可以设置一个公共属性来封装它吗

e、 g

我没有得到任何错误,但是如果某个东西是常量,我真的不理解为什么要封装它。我真的很想知道为什么会这样:

  • 对/错
  • 为什么要这样做
  • 福利

  • 即使某些内容是常量,您仍然需要控制如何将其返回给调用方。如果您有一个双变量,该变量存储到小数点后5位,那么您可能希望在小数点后2位将值返回给调用方。封装帮助您获得对字段的这种控制

    所以您可能需要像这样封装一个常量字段

    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
    ,并注意Jeroen Mostert关于常量内联的评论。

    据我所知,您可以创建私有常量的公共访问器,没有问题

    在以下情况下,应创建常量的访问器:

  • 如果条件适用,您需要向getter添加额外的逻辑,比如以某种方式格式化的return或其他值
  • 常量是用作其他命名空间库的命名空间的一部分,因为如果编译常量所在的命名空间,从属命名空间将只记住常量的旧值,因为它是在编译时定义的

  • 重要的是要知道常量是由编译器内联的。这意味着这两个示例产生相同的程序:

    private const int DEFAULT_CHARGE = 200;
    public int default_charge
    {
         get { return DEFAULT_CHARGE; }
    }
    
    与此相同,编译后:

    public int default_charge
    {
         get { return 200; }
    }
    
    如您所见,对
    DEFAULT\u CHARGE
    的引用在编译后丢失。对于在多个项目中重用相同常量的解决方案,记住这一点很重要

    假设您在LibA和LibB中使用
    DEFAULT\u CHARGE
    作为
    public const
    。项目经理告诉您将值从200更改为300。本能地,您转到定义了
    DEFAULT\u CHARGE
    的LibA,将其更改为300,然后重新编译并仅部署LibA

    结果是LibA现在使用新值300,但LibB继续使用旧值200,因为常量在编译时被烘焙到DLL中

    之所以可以封装该常量,是为了更容易地更改该值。需求往往会随着时间的推移而变化。当前不变的
    默认\u费用
    值将来可能必须替换为配置值


    通过封装常量,还可以防止我刚才解释的问题。如果LibA和LibB(以及LibX、LibY、LibZ,…)都依赖于封装,则只需重新编译和部署LibA即可在所有依赖程序中设置默认费用。

    一个非常重要的原因:编译器可以(也将)在编译常量的位置展开常量。换句话说,在重新编译之前,更改值并分发新程序集不会导致客户端实际使用新值。有时这是你想要的,通常不是(其他时候也没关系,因为你不会更换单个组件)。你们是最好的,非常感谢!我想我现在明白了背后的理论和理由!真希望有一天我能达到你的水平!:)这是一个非常清楚的解释,非常感谢!非常感谢你!真的很有帮助
    private const int DEFAULT_CHARGE = 200;
    public int default_charge
    {
         get { return DEFAULT_CHARGE; }
    }
    
    public int default_charge
    {
         get { return 200; }
    }