简体   繁体   English

构造函数和属性设置为私有或公共

[英]Constructors and properties being set to private or public

I am creating a class in C# and am being told that all of my properties should be public.我正在 C# 中创建一个 class 并被告知我的所有属性都应该是公开的。 I was taught that information hiding is common in C++ but idk if it is the same is C# or if the convention for doing so is different.我被告知信息隐藏在 C++ 中很常见,但如果它相同,则 idk 是 C# 或者如果这样做的约定不同。 The first example is how I was taught to do it.第一个例子是我是如何被教导去做的。 The 2nd example is how I am being taught to implement this class now.第二个例子是我现在被教导如何实现这个 class。 My question is this: Will this prevent me from using any of the properties with other classes or will it all work because of the constructor making them public?我的问题是:这会阻止我将任何属性与其他类一起使用,还是会因为构造函数将它们公开而全部工作?

Thank you all in advance谢谢大家

    class Book
    {
        string Title = null;
        string Author = null;
        int Year = 0;
        string CoverType = null;

        public Book (string aTitle, string anAuthor, int aYear, string aCoverType)
        {
            Title = aTitle;
            Author = anAuthor;
            Year = aYear;
            CoverType = aCoverType;
        }

Separation of examples示例分离

    
    public class Book
    {
        public string Title = null;
        public string Author = null;
        public int Year = 0;
        public string CoverType = null;

        public Book (string aTitle, string anAuthor, int aYear, string aCoverType)
        {
            Title = aTitle;
            Author = anAuthor;
            Year = aYear;
            CoverType = aCoverType;
        }


Will this prevent me from using any of the properties with other classes这会阻止我将任何属性与其他类一起使用吗

No. That's the definition of having public modifier.不,这就是拥有public修饰符的定义。

However, as written in the Microsoft documentation public fields are "Generally not recommended"但是,正如Microsoft 文档中所写,公共字段是“一般不推荐”

The common approach is to expose properties with backing fields .常见的方法是使用支持字段公开属性

public will make your fields accessible, but I think you want properties with auto getters/setters here. public将使您的字段可访问,但我认为您希望此处具有自动获取器/设置器的properties

The principle of encapsulation is one of the most important notions in object-oriented design.封装原则是面向对象设计中最重要的概念之一。 This principle states that data stored inside an object should be accessible only to that object.该原则规定,存储在 object 中的数据应该只能由该 object 访问。

A useful way to interpret the principle is to say that a type should be designed so that changes to fields of that type (name or type changes) can be made without breaking code other than for members of the type.解释该原则的一种有用方法是说应该设计一个类型,以便可以在不破坏该类型成员以外的代码的情况下对该类型的字段进行更改(名称或类型更改)。 This interpretation immediately implies that all fields must be private.这种解释立即意味着所有字段都必须是私有的。

❌ DO NOT provide instance fields that are public or protected. ❌ 不要提供公开或受保护的实例字段。

You should provide properties for accessing fields instead of making them public or protected.您应该提供用于访问字段的属性,而不是使它们公开或受保护。

https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/field https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/field

You should separate properties and fields , ie您应该将属性字段分开,即

private int year = 0; // field
public int Year { get { return year;}} // Property, wrapping the field
public int Year2  => year; // Same as above, using more compact syntax
public String Author {get;} // auto-property, automatically adds a hidden field

The typical rule is to keep fields private, and if you need public access, wrap them in a property, or use an auto property.典型的规则是保持字段私有,如果您需要公共访问,请将它们包装在属性中,或使用自动属性。 So it usually does not make much sense to make properties private, since the goal is usually to expose the underlying field.因此,将属性设为私有通常没有多大意义,因为目标通常是公开底层字段。

I would also recommend using readonly properties whenever practical, ie {get;} or {get; init;}我还建议在可行时使用只读属性,即{get;}{get; init;} {get; init;} . {get; init;} . If the property can never change, there is usually less problems with making it public.如果财产永远不会改变,那么公开它的问题通常会更少。

I suggest using properties instead of fields :我建议使用属性而不是字段

  • Let's set Title , ..., CoverType once in the consructor and prevent them form occasinal (erroneous) modifications让我们在构造函数中设置一次Title , ..., CoverType并防止它们形成偶然的(错误的)修改
  • Let's validate input arguments, let's not use null as placeholder.让我们验证输入 arguments,我们不要使用null作为占位符。

Code:代码:

public class Book
{
    public string Title     { get; }
    public string Author    { get; }
    public int Year         { get; }
    public string CoverType { get; }

    public Book (string aTitle, string anAuthor, int aYear, string aCoverType)
    {
        Title = aTitle?.Trim() 
          ?? throw new ArgumentNullException(nameof(aTitle));
        
        Author = anAuthor?.Trim() 
          ?? throw new ArgumentNullException(nameof(anAuthor));
        
        Year = aYear > 1400 && aYear <= DateTime.Now.Year + 1
          ? aYear
          : new ArgumentOutOfRangeException(nameof(aYear)); 

        CoverType = aCoverType ?? "";
    }

    ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么使用私有成员然后使用公共属性来设置它们? - Why use private members then use public properties to set them? 与构造函数相关的公共字段与属性 - Public fields vs. properties as they relate to constructors 公共属性,而不是PRIVATE字段 - Public Properties instead of PRIVATE fields 如何在运行时查找使用C#加载/执行的私有/公共类,属性和方法 - How to find out the private/public classes, properties, and methods being loaded/executed with C# during runtime 在公共实例上使用getter和setter设置该类的私有实例时,会设置哪个类实例的属性? - Which class instance's properties are set when using a getter and setter on a public instance to set a private instance of that class? 属性私人集; - Properties private set; 关于私有,公共和受保护构造函数的抽象类的一些问题 - Some questions about abstract class with private, public and protected constructors 如何使用公共属性而不是私有集合方法实现多个接口? - How do I implement multiple interfaces with public properties but private set methods? 公共与私人{get,set} - Public vs Private{get, set} 是否可以在派生类中设置基类设置中的私有setter而不公开? - Is it possible to have a private setter in base class set from derived class without being public?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM